ES2015中的箭头函数提供了更简洁的语法。
我现在可以用箭头函数替换所有函数声明/表达式吗?
我要注意什么?
例子:
构造函数
function User(name) {
this.name = name;
}
// vs
const User = name => {
this.name = name;
};
原型方法
User.prototype.getName = function() {
return this.name;
};
// vs
User.prototype.getName = () => this.name;
对象(文字)方法
const obj = {
getName: function() {
// ...
}
};
// vs
const obj = {
getName: () => {
// ...
}
};
回呼
setTimeout(function() {
// ...
}, 500);
// vs
setTimeout(() => {
// ...
}, 500);
可变函数
function sum() {
let args = [].slice.call(arguments);
// ...
}
// vs
const sum = (...args) => {
// ...
};
最佳答案
tl; dr:不!箭头函数和函数声明/表达式不等效,不能盲目替换。
如果要替换的函数不使用this
,arguments
并且未使用new
调用,则可以。
如此频繁:这取决于。箭头函数与函数声明/表达式的行为不同,因此让我们首先看一下它们的区别:
1.词法this
和arguments
箭头函数没有自己的this
或arguments
绑定。相反,这些标识符像任何其他变量一样在词法范围内解析。这意味着在箭头函数内部,this
和arguments
引用定义了箭头函数的环境中的this
和arguments
的值(即,箭头函数“外”):
// 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
在函数表达式的情况下,
this
指的是在createObject
内部创建的对象。在箭头功能情况下,this
指this
本身的createObject
。如果需要访问当前环境的
this
,这将使箭头功能有用:// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
请注意,这也意味着无法用
this
或.bind
设置箭头功能的.call
。如果您对
this
不太熟悉,请考虑阅读MDN - this
YDKJS - this & Object prototypes
2.箭头函数不能用
new
调用ES2015区分了可调用函数和可构造函数。如果一个函数是可构造的,则可以使用
new
即new User()
对其进行调用。如果一个函数是可调用的,则可以在不使用new
的情况下对其进行调用(即正常的函数调用)。通过函数声明/表达式创建的函数是可构造的和可调用的。
箭头函数(和方法)仅可调用。
class
构造函数只能构造。如果试图调用不可调用函数或构造不可构造函数,则会出现运行时错误。
知道了这一点,我们可以陈述以下内容。
可更换的:
不使用
this
或arguments
的函数。与
.bind(this)
一起使用的功能不可更换:
构造函数
添加到原型的函数/方法(因为它们通常使用
this
)可变参数函数(如果它们使用
arguments
(请参见下文))让我们使用您的示例仔细看一下:
构造函数
这是行不通的,因为箭头函数不能用
new
调用。继续使用函数声明/表达式或使用class
。原型方法
很有可能不是,因为原型方法通常使用
this
访问实例。如果他们不使用this
,则可以将其替换。但是,如果您主要关心简洁的语法,请使用class
及其简洁的方法语法:class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
对象方法
与对象文字中的方法类似。如果该方法要通过
this
引用对象本身,请继续使用函数表达式或使用新的方法语法:const obj = {
getName() {
// ...
},
};
回呼
这取决于。如果要别名外部
this
或使用.bind(this)
,则绝对应该替换它:// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
但是:如果调用回调的代码显式地将
this
设置为特定值(如事件处理程序,尤其是jQuery),并且回调使用this
(或arguments
),则不能使用箭头功能!可变函数
由于箭头函数没有自己的
arguments
,因此不能简单地用箭头函数替换它们。但是,ES2015引入了使用arguments
的替代方法:rest parameter。// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
相关问题:
When should I use Arrow functions in ECMAScript 6?
Do ES6 arrow functions have their own arguments or not?
What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?
How to use arrow functions (public class fields) as class methods?
更多资源:
MDN - Arrow functions
YDKJS - Arrow functions
关于javascript - “箭头功能”和“功能”是否等效/可互换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45527065/