感謝社區(qū)中各位的大力支持更米,譯者再次奉上一點點福利:阿里云產品券,享受所有官網優(yōu)惠,并抽取幸運大獎:點擊這里領取
這本書通篇沒有講解this
機制的任何細節(jié)印叁,有一個ES6的話題以一種重要的方式將this
與詞法作用域聯(lián)系了起來曹仗,我們將快速檢視它一下榨汤。
ES6為函數(shù)聲明增加了一種特殊的語法形式,稱為“箭頭函數(shù)”怎茫。它看起來像這樣:
var foo = a => {
console.log( a );
};
foo( 2 ); // 2
這個所謂的“大箭頭”經常被稱為是 乏味煩冗的(諷刺)function
關鍵字的縮寫收壕。
但是在箭頭函數(shù)上發(fā)生的一些事情要重要得多,而且這與在你的聲明中少敲幾下鍵盤無關。
簡單地說蜜宪,這段代碼有一個問題:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome
這個問題就是在cool()
函數(shù)上丟失了this
綁定虫埂。有各種方法可以解決這個問題,但一個經常被重復的解決方案是var self = this;
圃验。
它可能看起來像:
var obj = {
count: 0,
cool: function coolFn() {
var self = this;
if (self.count < 1) {
setTimeout( function timer(){
self.count++;
console.log( "awesome?" );
}, 100 );
}
}
};
obj.cool(); // awesome?
用不過于深入細節(jié)的方式講掉伏,var self = this
的“解決方案”免除了理解和正確使用this
綁定的整個問題,而是退回到我們也許感到更舒服的東西上面:詞法作用域损谦。self
變成了一個可以通過詞法作用域和閉包解析的標識符岖免,而且一直不關心this
綁定發(fā)生了什么。
人們不喜歡寫繁冗的東西照捡,特別是當他們一次又一次重復它的時候颅湘。于是,ES6的一個動機是幫助緩和這些場景栗精,將常見的慣用法問題 固定 下來闯参,就像這一個。
ES6的解決方案悲立,箭頭函數(shù)鹿寨,引入了一種稱為“詞法this”的行為。
var obj = {
count: 0,
cool: function coolFn() {
if (this.count < 1) {
setTimeout( () => { // 箭頭函數(shù)能好用薪夕?
this.count++;
console.log( "awesome?" );
}, 100 );
}
}
};
obj.cool(); // awesome?
簡單的解釋是脚草,當箭頭函數(shù)遇到它們的this
綁定時,它們的行為與一般的函數(shù)根本不同原献。它們摒棄了this
綁定的所有一般規(guī)則馏慨,而是將它們的立即外圍詞法作用域作為this
的值,無論它是什么姑隅。
于是写隶,在這個代碼段中,箭頭函數(shù)不會以不可預知的方式丟掉this
綁定讲仰,它只是“繼承”cool()
函數(shù)的this
綁定慕趴。
雖然這使代碼更短,但在我看來鄙陡,箭頭函數(shù)只不過是將一個開發(fā)者們常犯的錯誤固化成了語言的語法冕房,這混淆了“this綁定”規(guī)則與“詞法作用域”規(guī)則。
換一種說法:為什么要使用this
風格的編碼形式來招惹麻煩和繁冗趁矾?只要通過將它與詞法作用域混合把它剔除掉就好毒费。對于給定的一段代碼只采納一種方式或另一種看起來才是自然的,而不是在同一段代碼中將它們混在一起愈魏。
注意: 源自箭頭函數(shù)的另一個非議是,它們是匿名的,不是命名的培漏。參見第三章來了解為什么匿名函數(shù)不如命名函數(shù)理想的原因溪厘。
在我看來,這個“問題”的更恰當?shù)慕鉀Q方式是牌柄,正確地使用并接受this
機制畸悬。
var obj = {
count: 0,
cool: function coolFn() {
if (this.count < 1) {
setTimeout( function timer(){
this.count++; // `this` 因為 `bind(..)` 所以安全
console.log( "more awesome" );
}.bind( this ), 100 ); // 看,`bind()`!
}
}
};
obj.cool(); // more awesome
不管你是偏好箭頭函數(shù)的新的詞法this行為珊佣,還是偏好經得起考驗的bind()
蹋宦,重要的是要注意箭頭函數(shù) 不 僅僅是關于可以少打一些“function”。
它們擁有一種我們應當學習并理解的咒锻,有意的行為上的不同冷冗,而且如果我們這樣選擇,就可以利用它們惑艇。
現(xiàn)在我們完全理解了詞法作用域(和閉包]镎蕖),理解詞法this應該是小菜一碟滨巴!