tl;dr: 不行! 箭头函数和函数声明/表达式不等价,不能盲目替换。
如果要替换的函数不使用this
、arguments
,并且没有使用new
调用,则可以。
常规而言:视情况而定。箭头函数与函数声明/表达式具有不同的行为,因此让我们先看一下它们之间的区别:
1. 词法作用域中的this
和arguments
箭头函数没有自己的this
或arguments
绑定。相反,这些标识符在词法作用域中像任何其他变量一样进行解析。这意味着在箭头函数内部,this
和arguments
指的是环境中的this
和arguments
的值,即箭头函数所在的环境(即"外部"箭头函数)中的值:
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar();
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar();
在函数表达式的情况下,
this
指的是在
createObject
内部创建的对象。而在箭头函数中,
this
指的是
createObject
本身的
this
。
这使得箭头函数在需要访问当前环境的
this
时非常有用。
var that = this;
getData(function(data) {
that.data = data;
});
getData(data => {
this.data = data;
});
注意,这也意味着无法使用 .bind
或 .call
来设置箭头函数的 this
。
如果你对 this
不是很熟悉,建议阅读:
2. 箭头函数不能通过 new
调用
ES2015 区分了可调用和可构造函数。如果一个函数可以被构造,它可以通过 new
调用,例如 new User()
。如果一个函数可以被调用,它可以在没有 new
的情况下被调用(即正常函数调用)。
函数声明/表达式创建的函数既可以构造也可以调用。
箭头函数(和方法)只能被调用。
class
构造函数只能被构造。
如果您试图调用一个不可调用的函数或构造一个不可构造的函数,将会出现运行时错误。
了解这一点后,我们可以得出以下结论:
可以替换的:
- 不使用
this
或 arguments
的函数。
- 与
.bind(this)
一起使用的函数
无法 替换的:
- 构造函数
- 添加到原型中的函数/方法(因为它们通常使用
this
)
- 变参函数(如果它们使用
arguments
(见下文))
- 生成器函数,需要使用
function*
表示法
让我们使用您提供的示例更详细地看看这些内容:
构造函数
这不起作用,因为箭头函数不能通过 new
调用。继续使用函数声明/表达式或使用 class
。
原型方法
很可能不行,因为原型方法通常使用 this
访问实例。如果它们不使用 this
,则可以替换它们。但是,如果您主要关心简洁的语法,请使用 class
和其简洁的方法语法:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
对象方法
对于对象字面量中的方法同样适用。如果方法想要通过 this
引用对象本身,请继续使用函数表达式或使用新的方法语法:
const obj = {
getName() {
},
};
回调函数
这取决于情况。如果你正在别名化外部的this
,或者正在使用.bind(this)
,那么你应该肯定要替换它:
setTimeout(function() {
}.bind(this), 500);
setTimeout(() => {
}, 500);
但是: 如果调用回调函数的代码显式地将this
设置为特定值,这在事件处理程序中经常发生,特别是在jQuery中,而回调函数使用this
(或arguments
),则不能使用箭头函数!
可变参数函数
由于箭头函数没有自己的arguments
,因此您不能简单地将它们替换为箭头函数。但是,ES2015引入了一种替代方案来使用arguments
: rest参数。
function sum() {
let args = [].slice.call(arguments);
}
const sum = (...args) => {
};
相关问题:
更多资源:
this
很不同,每次调用按钮时timesCalled
只增加 1。这回答了我的个人问题:.click( () => { } )
和.click(function() { })
在循环中使用时都创建相同数量的函数,正如你可以从 Plnkr 中的 Guid 计数中看到的那样。 - jmbmage