04-箭头函数
9.3 箭头函数
如果你看了Node的API文档,就会发现ES6中使用最广泛的功能是箭头函数。箭头函数会做两件事情,第一件是提供了简化的语法。比如在前面的章节中,我这样来创建一个新的HTTP服务:
http.createServer(function (req, res) {
res.writeHead(200);
res.write('Hello');
res.end();
}).listen(8124);
有了箭头函数,我就可以将上面的代码重写为:
http.createServer( (req, res) => {
res.writeHead(200);
res.write('Hello');
res.end();
}).listen(8124);
function
关键字被去掉了,而胖箭头(=>)用来表示一个传入给定参数的匿名函数。而且还可以进一步简化。比如下面这种熟悉的函数模式:
var decArray = [23, 255, 122, 5, 16, 99];
var hexArray = decArray.map(function(element) {
return element.toString(16);
});
console.log(hexArray); // ["17", "ff", "7a", "5", "10", "63"]
可以简化为:
var decArray = [23, 255, 122, 5, 16, 99];
var hexArray = decArray.map(element => element.toString(16));
console.log(hexArray); // ["17", "ff", "7a", "5", "10", "63"]
花括号、 return
语句和 function
关键字都被去掉了,代码已经被简化到了极致。
箭头函数不只是语法上的简化,它同时也重新定义了 this
关键字,这是它做的第二件事情。在JavaScript中,在箭头函数出现以前,每个函数都会定义自己的 this
。所以在下面的代码中,被打印到控制台的并不是我的名字,而是 undefined
:
function NewObj(name) {
this.name = name;
}
NewObj.prototype.doLater = function() {
setTimeout(function() {
console.log(this.name);
}, 1000);
};
var obj = new NewObj('shelley');
obj.doLater();
原因是 this
在构造函数中被指向了实例本身,而后面的 setTimeout
改变了 this
的指向。我们可以借助另外一个变量来解决这个问题,通常我们使用 self
,这个变量是封闭的(不会因为环境的改变而变化)。下面的代码就会得到正确的结果,即将我的名字打印出来:
function NewObj(name) {
this.name = name;
}
NewObj.prototype.doLater = function() {
var self = this;
setTimeout(function() {
console.log(self.name);
}, 1000);
};
var obj = new NewObj('shelley');
obj.doLater();
而在箭头函数中, this
总是指向它通常所指向的那个封闭上下文中的对象。在本例中就是新创建出来的 new
对象:
function NewObj(name) {
this.name = name;
}
NewObj.prototype.doLater = function() {
setTimeout(()=> {
console.log(this.name);
}, 1000);
};
var obj = new NewObj('shelley');
obj.doLater();
**规避箭头函数中的坑** 箭头函数里面也有坑,比如如何返回一个空对象,以及参数在哪里。Strongloop针对箭头函数写了一篇文章,专门介绍箭头函数中的坑和规避方法。