不綁定this
在箭頭函數出現之前,每個新定義的函數都有它自己的 this
值(在構造函數的情況下是一個新對象,在嚴格模式的函數調用中爲 undefined,如果該函數被作爲“對象方法”調用則爲基礎對象等)。This
被證明是令人厭煩的面向對象風格的編程。
function Person() {
// Person() 構造函數定義 `this`作爲它自己的實例.
this.age = 0;
setInterval(function growUp() {
// 在非嚴格模式, growUp()函數定義 `this`作爲全局對象,
// 與在 Person()構造函數中定義的 `this`並不相同.
this.age++;
}, 1000);
}
var p = new Person();
在ECMAScript 3/5中,通過將this
值分配給封閉的變量,可以解決this
問題。
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
// 回調引用的是`that`變量, 其值是預期的對象.
that.age++;
}, 1000);
}
或者,可以創建綁定函數,以便將預先分配的this
值傳遞到綁定的目標函數(上述示例中的growUp()
函數)。
箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this
。因此,在下面的代碼中,傳遞給setInterval
的函數內的this
與封閉函數中的this
值相同:
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| 正確地指向person 對象
}, 1000);
}
var p = new Person();
與嚴格模式的關係
鑑於 this
是詞法層面上的,嚴格模式中與 this
相關的規則都將被忽略。
function Person() {
this.age = 0;
var closure = "123"
setInterval(function growUp() {
this.age++;
console.log(closure)
}, 1000);
}
var p = new Person();
function PersonX() {
'use strict'
this.age = 0;
var closure = "123"
setInterval(()=>{
this.age++;
console.log(closure)
}, 1000);
}
var px = new PersonX();
嚴格模式的其他規則依然不變.