ES6 Arrow Functions
Bài đăng này đã không được cập nhật trong 6 năm
Mở đầu
Trong ES6, arrow functions là một cú pháp mới dùng để viết các hàm trong JavaScript. Nó giúp tiết kiệm thời gian phát triển và đơn giản hóa phạm vi function (function scope). Trong bài viết này, mình sẽ giới thiệu chi tiết về arrow function, cách sử dụng chúng, các cú pháp phổ biến, trường hợp sử dụng phổ biến, cũng như ưu/nhược điểm của việc sử dụng chúng.
Arrow function là gì
Arrow function - còn được gọi là "fat arrow", là cú pháp được mượn từ CoffeeScript (một ngôn ngữ chuyển tiếp), cú pháp này là cách ngắn gọn hơn dùng để viết function. Ở đây sử dụng kí tự =>
, trông giống như một mũi tên "béo". Arrow function là một hàm vô danh và nó thay đổi cách this
bind đến function.
Arrow function làm code của ta trông ngắn gọn hơn, giúp đơn giản hóa function scoping cũng như từ khóa this
. Arrow function hoạt động tương tự như Lambdas
trong các ngôn ngữ khác như C # hay Python. Bằng cách sử dụng arrow function, chúng ta tránh được việc phải gõ từ khoá function
, return
và dấu ngoặc nhọn.
Cách dùng arrow function
Có khá nhiều cú pháp có thể dùng với arrow function. EcmaScript.org, MDN có liệt kê một danh sách đầy đủ các cú pháp có thể được dùng. Ở đây tôi sẽ đề cập đến những cú pháp phổ biến nhất.
Trong trường hợp nhiều tham số
// (param1, param2, paramN) => expression
// ES5
var multiply = function(x, y) {
return x * y;
};
// ES6
var multiply = (x, y) => { return x * y };
Ví dụ trên cho cùng một kết quả, tuy nhiên cú pháp với arrow function tốn ít dòng mã hơn. Trong trường hợp chỉ có một biểu thức thì không cần tới dấu ngoặc nhọn: Ví dụ trên có thể viết lại như sau:
var multiply = (x, y) => x * y ;
Trong trường hợp 1 tham số
Dấu ngoặc đơn là optional khi chỉ có một tham số
//ES5
var phraseSplitterEs5 = function phraseSplitter(phrase) {
return phrase.split(' ');
};
//ES6
var phraseSplitterEs6 = phrase => phrase.split(" ");
console.log(phraseSplitterEs6("ES6 Awesomeness")); // ["ES6", "Awesomeness"]
Trong trường hợp không có tham số
Dấu ngoặc đơn là bắt buộc khi không có tham số.
//ES5
var docLogEs5 = function docLog() {
console.log(document);
};
//ES6
var docLogEs6 = () => { console.log(document); }
docLogEs6(); // #document... <html> ….
Cú pháp với Object literal
Arrow function cũng tương tự như biểu thức function, có thể được sử dụng để trả về một object literal. Phần body của function cần được bao bọc trong ngoặc tròn, để phân biệt giữa object và function block (cả hai đều sử dụng dấu ngoặc nhọn).
//ES5
var setNameIdsEs5 = function setNameIds(id, name) {
return {
id: id,
name: name
};
};
// ES6
var setNameIdsEs6 = (id, name) => ({ id: id, name: name });
(setNameIdsEs6 (4, "Kyle")); // Object {id: 4, name: "Kyle"}
Khi nào thì nên sử dụng arrow function
Một usecase phổ biến áp dung arrow function là thao tác mảng, thông thường là khi dùng map
hoặc reduce
. Có 1 mảng như sau:
var smartPhones = [
{ name: 'iphone', price: 649 },
{ name: 'Galaxy S6', price: 576 },
{ name: 'Galaxy Note 5', price: 489 }
];
Để lấy 1 mảng toàn tên các smart phones, ta thực hiện:
// ES5
console.log(smartPhones.map(function(smartPhone){
return smartPhone.price;
}); // [649, 576, 489]
Với arrow function, có thể viết rút gọn lại thành
// ES6
console.log(smartPhones.map(smartPhone => smartPhone.price)); // [649, 576, 489]
Promises và Callbacks
Code mà sử dụng các callback asynchronous hay promise thường chứa nhiều từ khóa function
và return
do chaining nhiều lần:
// ES5
aAsync().then(function() {
returnbAsync();
}).then(function() {
returncAsync();
}).done(function() {
finish();
});
Sử dụng arrow function:
// ES6
aAsync().then(() => bAsync()).then(() => cAsync()).done(() => finish);
Lưu ý trong việc sử dụng arrow function
Cú pháp arrrow function là chức năng khá hữu ích trong ECMAScript, tuy nhiên ngoài những ưu điểm thì nó cũng có những hạn chế như việc nó khiến code của bạn tuy ngắn nhưng lại khó hiểu. Dưới đây là những lưu ý
this
từ khóa this
hoạt động khác hoàn toàn trong arrow function. Các phương thức call (), apply (), và bind () sẽ không thay đổi giá trị của this
trong arrow function. (Trong thực tế, giá trị của this
bên trong một hàm đơn giản là không thể thay đổi - nó sẽ luôn là giá trị tương tự như khi hàm được gọi) Nếu bạn cần bind đến một giá trị khác, cần sử dụng function expression như bình thường.
Constructors
Arrow function không thể được sử dụng làm constructor như function. Nếu khởi tạo new
với arrow function, nó sẽ throw ra lỗi. Arrow function không có thuộc tính prototype
hay internal methods. Trong trường hợp đó nên dùng cú pháp tạo class của ES6.
Generators
Arrow function được thiết kế không thể sử dụng như là generator. Thay vào đó ta có thể sử dụng từ khóa generators
trong ES6.
Tốt nhất nên cân đối giữa việc dùng function
và dùng arrow function
như sau:
- Sử dụng function trong global scope trong Object.prototype properties
- Sử dụng class cho object constructors.
- Sử dụng
=>
ở những chố còn lại
Nguồn tham khảo
All rights reserved