tl; dr: Không! Hàm mũi tên và khai báo hàm / biểu thức không tương đương và không thể thay thế một cách mù quáng.
Nếu chức năng bạn muốn thay thế không không sử dụng this
, arguments
và không được gọi với new
, sau đó có.
Như thường lệ: nó phụ thuộc . Các hàm mũi tên có hành vi khác với khai báo / biểu thức hàm, vì vậy trước tiên chúng ta hãy xem xét sự khác biệt:
1. Từ điển this
vàarguments
Các hàm mũi tên không có ràng buộc riêng this
hoặc arguments
ràng buộc. Thay vào đó, những định danh được giải quyết trong phạm vi từ vựng như bất kỳ biến nào khác. Điều đó có nghĩa là bên trong hàm mũi tên this
và arguments
tham chiếu đến các giá trị của this
và arguments
trong môi trường, hàm mũi tên được xác định trong (tức là "bên ngoài" hàm mũi tên):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
Trong trường hợp biểu thức hàm, this
tham chiếu đến đối tượng được tạo bên trong createObject
. Trong trường hợp mũi tên chức năng, this
đề cập đến this
của createObject
chính nó.
Điều này làm cho các chức năng mũi tên trở nên hữu ích nếu bạn cần truy cập vào this
môi trường hiện tại:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Lưu ý rằng điều này cũng có nghĩa là không thể đặt chức năng mũi tên this
bằng .bind
hoặc .call
.
Nếu bạn không quen thuộc lắm this
, hãy cân nhắc đọc
2. Chức năng mũi tên không thể được gọi với new
ES2015 phân biệt giữa các chức năng có khả năng gọi và chức năng có thể xây dựng . Nếu một chức năng là có thể xây dựng, nó có thể được gọi với new
, tức là new User()
. Nếu một chức năng có thể gọi được, nó có thể được gọi mà không có new
(tức là gọi chức năng bình thường).
Các hàm được tạo thông qua các khai báo / biểu thức hàm đều có thể xây dựng và có thể gọi được.
Các hàm mũi tên (và phương thức) chỉ có thể gọi được.
class
nhà xây dựng chỉ có thể xây dựng.
Nếu bạn đang cố gắng gọi một chức năng không thể gọi được hoặc để xây dựng một chức năng không thể xây dựng, bạn sẽ gặp lỗi thời gian chạy.
Biết điều này, chúng ta có thể nói như sau.
Có thể thay thế:
- Các chức năng không sử dụng
this
hoặc arguments
.
- Các hàm được sử dụng với
.bind(this)
Không thể thay thế:
- Hàm xây dựng
- Hàm / phương thức được thêm vào nguyên mẫu (vì chúng thường sử dụng
this
)
- Các hàm biến thể (nếu chúng sử dụng
arguments
(xem bên dưới))
Hãy xem xét kỹ hơn điều này bằng các ví dụ của bạn:
Hàm xây dựng
Điều này sẽ không hoạt động vì các chức năng mũi tên không thể được gọi với new
. Tiếp tục sử dụng một khai báo / biểu thức chức năng hoặc sử dụng class
.
Phương pháp nguyên mẫu
Nhiều khả năng là không, bởi vì các phương thức nguyên mẫu thường sử dụng this
để truy cập thể hiện. Nếu họ không sử dụng this
, thì bạn có thể thay thế nó. Tuy nhiên, nếu bạn chủ yếu quan tâm đến cú pháp súc tích, hãy sử dụng class
với cú pháp phương thức súc tích của nó:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Phương thức đối tượng
Tương tự cho các phương thức trong một đối tượng bằng chữ. Nếu phương thức muốn tham chiếu chính đối tượng thông qua this
, hãy tiếp tục sử dụng các biểu thức hàm hoặc sử dụng cú pháp phương thức mới:
const obj = {
getName() {
// ...
},
};
Gọi lại
Nó phụ thuộc. Bạn chắc chắn nên thay thế nó nếu bạn đang răng cưa bên ngoài this
hoặc đang sử dụng .bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Nhưng: Nếu mã gọi lại gọi lại rõ ràng this
thành một giá trị cụ thể, như trường hợp thường gặp với các trình xử lý sự kiện, đặc biệt là với jQuery và gọi lại sử dụng this
(hoặc arguments
), bạn không thể sử dụng hàm mũi tên!
Chức năng biến thể
Vì các hàm mũi tên không có riêng arguments
, bạn không thể thay thế chúng bằng hàm mũi tên. Tuy nhiên, ES2015 giới thiệu một cách thay thế cho việc sử dụng arguments
: tham số phần còn lại .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Câu hỏi liên quan:
Tài nguyên khác: