Cảm ơn bạn!
Arrow Function JavaScript có gì hay?
Arrow Function JavaScript là một trong những tính năng được giới thiệu trong phiên bản JavaScript ES6. Nó cho phép chúng ta tạo các functions một cách gọn gàng hơn so với các function thông thường. Cùng tìm hiểu về nó thông qua bài viết này nhé!
JavaScript Arrow Function
Để hiểu hơn về JavaScript Arrow Function mình sẽ tạo một ví dụ như sau:
// function expression
let x = function(x, y) {
return x * y;
}
Ở trên là một function expression chúng ta thường tạo. Nó có thể được viết lại như sau:
// sử dụng arrow function
let x = (x, y) => x * y;
Các bạn thấy khi sử dụng arrow function thì code của chúng ta trở nên rất ngắn gọn đúng không 😁. Bây giờ chúng ta cùng tìm hiểu về cú pháp của arrow function nhé.
Arrow Function Syntax
Cú pháp của Arrow Function như sau:
let myFunction = (arg1, arg2, ...argN) => {
// thân hàm
}
Trong đó:
- myFunction là tên của hàm
- arg1, arg2, ... argN là các đối số của hàm
Nếu thân hàm chỉ có một câu lệnh hoặc biểu thức, chúng ta có thể viết gọn lại như sau:
// viết gọn lại thành 1 dòng
let myFunction = (arg1, arg2, ...argN) => expression
Ví dụ Arrow Function
Nếu hàm không nhận bất kỳ đối số nào, thì chúng ta sử dụng dấu ngoặc đơn ()
trống.
let greet = () => console.log('Đây là blog homiedev.com');
greet(); // Đây là blog homiedev.com
Với hàm có 1 đối số thì chúng ta có thể viết gọn như sau:
let greet = x => console.log(x);
greet('Xin chào! đây là blog homiedev.com');
Như các bạn thấy chúng ta có thể bỏ qua ngoặc đơn như ở trên khi hàm có 1 đối số.
Chúng ta có thể sử dụng Arrow Function trong một biểu thức:
let age = 22;
let welcome = (age < 18) ?
() => console.log('Baby') :
() => console.log('Adult');
welcome(); // Adult
Nếu thân hàm có nhiều câu lệnh, chúng ta cần đặt chúng bên trong dấu ngoặc nhọn {}
:
let sum = (a, b) => {
let result = a + b;
return result;
}
let result = sum(5,5);
console.log(result); // 10
Bên trong một hàm thông thường, từ khóa this
sẽ thay đổi theo cách mà hàm đó được gọi:
- Gọi hàm kiểu thông thường:
this
sẽ là global object hoặc có thể undefined nếu bạn đang sử dụng strict mode. - Gọi kiểu method:
this
sẽ tương đương với object sở hữu method đó. - Gọi kiểu Constructor:
this
sẽ tương đương với đối tượng mới được tạo ra.
Tuy nhiên, điều này lại không giống ở Arrow Function. Bất cứ khi nào chúng ta sử dụng this
trong Arrow Function, nó đề cập đến phạm vi bên ngoài, chứa nó (parent scope). Giá trị this
bên trong của một Arrow Function luôn bằng với giá trị this
của hàm chứa nó.
Đối với hàm thông thường:
function Person() {
this.name = 'Trinh',
this.age = 22,
this.sayMyName = function () {
// sử dụng this
console.log(this.age);
function innerFunc() {
// this trỏ đến global object
console.log(this.age);
console.log(this);
}
innerFunc();
}
}
let x = new Person();
x.sayName();
Ở ví dụ trên, this.age
bên trong this.sayMyName()
có thể truy xuất được vì this.sayMyName()
là method của một object.
Tuy nhiên, innerFunc()
là một hàm thông thường cho nên this.age
sẽ không thể truy xuất được vì lúc này this
là đối tượng toàn cục (Window object). Do đó, this.age
bên trong hàm innerFunc()
cho giá trị undefined.
Kết quả của ví dụ trên sẽ là:
22
undefined
Window {}
Đối với Arrow Function sẽ có một chút khác biệt như sau:
function Person() {
this.name = 'Trinh',
this.age = 22,
this.sayMyName = function () {
console.log(this.name);
let innerFunc = () => {
console.log(this.name);
}
innerFunc();
}
}
const x = new Person();
x.sayMyName();
Kết quả sẽ là:
Trinh
Trinh
Ở ví dụ trên, hàm innerFunc()
được định nghĩa bằng cách sử dụng Arrow Function. Và bên trong hàm, this
sẽ trỏ đến scope bên ngoài chứa nó. Do đó, this.name cho kết quả như trên.
Bạn có thể đọc thêm các bài viết liên quan đến scope nhé:
- Scope trong JavaScript là gì?
- Tìm hiểu về lexical scope trong JavaScript.
- Closure trong JavaScript là gì?
- Tìm hiểu về Variable Scope trong JavaScript
- Hoisting trong JavaScript
Arguments Binding
Các hàm thông thường có các Arguments Binding (đối số ràng buộc). Đây chính là lý do tại sao khi chúng ta truyền các đối số cho một hàm thông thường, thì ta có thể truy cập chúng bằng cách sử dụng từ khóa arguments
.
Ví dụ:
let x = function () {
console.log(arguments);
}
x(1,2,3); // [1, 2, 3]
Ngược lại, với Arrow Function sẽ không có Arguments Binding.
Khi chúng ta thử sử dụng từ khóa arguments
, nó sẽ báo lỗi.
Ví dụ:
let x = () => {
console.log(arguments);
}
x(1,2,3);
// lỗi arguments is not defined
Khi sử dụng Arrow Function, bạn muốn lấy các đối số đã truyền dưới dạng một mảng thì chúng ta sẽ sử dụng spread syntax như sau:
let x = (...n) => {
console.log(n);
}
x(1,2,3); // [1, 2, 3]
Bài viết liên quan đến spread syntax các bạn có thể tham khảo tại:
Promises và Callbacks sử dụng Arrow Function
Chúng ta có thể viết các Promises và Callbacks trong JavaScript sử dụng Arrow Function vì cú pháp của nó ngắn gọn hơn.
Ví dụ:
// ES5, viết theo cách sử dụng hàm thông thường
asyncFunction().then(function() {
return asyncFunction1();
}).then(function() {
return asyncFunction2();
}).then(function() {
finish;
});
Ví dụ trên chúng ta có thể viết như sau:
// ES6, sử dụng Arrow Function
asyncFunction()
.then(() => asyncFunction1())
.then(() => asyncFunction2())
.then(() => finish);
Các bạn có thể thấy code đã gọn lại hơn nhiều rồi đúng không ^^.
Trường hợp tránh sử dụng Arrow Functions
Trong trường hợp dưới đây chúng ta nên tránh sử dụng Arrow Function nhé ^^.
- Không nên sử dụng Arrow Functions để tạo các method bên trong các objects.
let person = {
name: 'Minh',
age: 22,
sayName: () => {
// this sẽ trỏ đến global object
console.log(this.age);
}
}
person.sayName(); // undefined
- Chúng ta không thể sử dụng Arrow Functions làm constructor
let Person = () => {};
let person1 = new Person(); // Uncaught TypeError: Person is not a constructor
Như vậy là chúng ta đã tìm hiểu xong Arrow Function trong JavaScript. Hi vọng bài viết có ích cho các bạn.
Nếu có thắc mắc hay góp ý chúng ta cùng nhau thảo luận dưới phần bình luận của bài viết nhé 😁. Chúc các bạn học tốt