在JS中,箭頭函數並不是簡單的function(){}匿名函數的簡寫語法糖,實際上,箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法作用域,在編寫函數時就已經確定了。而匿名函數的this指向運行時實際調用該方法的對象,無法在編寫函數時確定。
我們看一下下面的例子:
function Test() {
this.num = 100;
this.func = function(){
console.log(this.num); // 100
setTimeout(function(){
console.log(this.num); // undefined
}, 500);
};
}
var obj = new Test();
obj.func();
這裏的方法裏調用了setTimeout函數,該函數500毫秒後調用我們定義的函數時,實際上是window對象調用的,所以這時匿名函數的this是指向window而不是指向obj了。
在箭頭函數出現之前一般都是這麼寫的:
function Test() {
this.num = 100;
this.func = function(){
console.log(this.num); // 100
var that = this;
setTimeout(function(){
console.log(that.num); // 100
}, 500);
};
}
var obj = new Test();
obj.func();
這是利用了閉包的概念。箭頭函數可以看做這種方式的語法糖。
如下:
function Test() {
this.num = 100;
this.func = function(){
console.log(this.num); // 100
setTimeout(() => {
console.log(this.num); // 100
}, 500);
};
}
var obj = new Test();
obj.func();
箭頭函數和普通函數的區別
- 不可以當做構造函數,也就是說,不可以使用 new 命令,否則會拋出錯誤。
- this、arguments、caller等對象在函數體內都不存在。
- 不可以使用 yield 命令,因此箭頭函數不能用作 Generator 函數。
總結
箭頭函數除了傳入的參數之外,其它的對象都沒有!在箭頭函數引用了this、arguments或者參數之外的變量,那它們一定不是箭頭函數本身包含的,而是從父級作用域繼承的。