原文链接:https://javascript.info/arrow-functions,translate with ❤️ by zhangbao.
让我们来重访箭头函数。
箭头可不仅是写法上的一个“简写”。
JavaScript 充满了需要去写那种微函数的地方。
例如:
arr.forEach(func):func 在每次 forEach 每个数组元素项的时候,被执行。
setTimout(func):func 被内置的调度器执行。
还有更多。
It’s in the very spirit of JavaScript to create a function and pass it somewhere.
在这种情况下,我们通常不希望离开当前上下文环境。
箭头函数没有“this”
我们记得在《对象方法,“this”》一章中,箭头函数没有 this,如果访问 this,它其实是外部的 this。
例如,我们可以在对象方法里有遍历逻辑时,使用它:
let group = {
title: 'Our Group',
students: ['John', 'Pete', 'Alice'],
showList() {
this.students.forEach(
student => alert(this.title + ':' + student);
);
}
};
在 forEach 里使用了箭头函数,所以在箭头函数里使用的 this 就是外部 showList 里的 this。也就是 group.title。
如果我们使用一个“常规”函数,就会出现一个错误:
let group = {
title: "Our Group",
students: ["John", "Pete", "Alice"],
showList() {
this.students.forEach(function(student) {
// undefiend。这里的 this 是指 window
alert(this.title + ': ' + student)
});
}
};
group.showList();
之所以出现错误,是因为在默认情况下,forEach 运行函数 this 是 window,所以访问结果是 undefined。
这并不影响箭头函数,因为它们没有 this。
注:箭头函数不能使用 new 调用
没有 this 意味着箭头函数有个限制:不能当做构造函数使用,也就是不能使用 new 调用。
注:箭头函数 VS bind
箭头函数 => 和常规函数的 bind(this) 调用略有不同:
.bind(this) 创建一个“绑定版本”的函数。
箭头函数 => 不创建任何绑定。因为函数没有 this。对 this 的查找和对普通变量查找几乎是一样的:在外部词法环境里。
箭头函数没有“arguments”
所有箭头函数里没有 arguments 变量。
这对于装饰器来说是很好的,当我们需要用当前 this 和 arguments 来转发一个调用时。
例如,defer(f, ms) 使用一个函数,返回一个包装了它的包装器,延迟到指定的毫秒数之后调用:
function defer(f, ms) {
return function() {
setTimeout(() => f.apply(this, arguments), ms)
};
}
function sayHi(who) {
alert('Hello, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("John"); // Hello, John after 2 seconds
没有箭头函数的版本是这样的:
function defer(f, ms) {
return function(...args) {
let ctx = this;
setTimeout(function() {
return f.apply(ctx, args);
}, ms);
};
}
在这里,我们必须创建额外的变量 args 和 ctx,以便 setTimeout 函数能够得到它们。
总结
箭头函数:
没有 this,
没有 arguments,
不能用 new 调用,
(也没有 super,我们还没学到。会在《类继承,super》一章里学到)。
这是因为它们的意思是微型代码,它们没有自己的“上下文”,而是在当前的上下文环境中工作的。它们在这样的用例中真的很闪亮。
(完)