我曾經(jīng)聽一位喜劇演員說過:
“我從未在這里,因?yàn)槲也磺宄@里是哪里,是除了那里之外的地方嗎?”
這句話或多或少地暗喻了在js開發(fā)中開發(fā)者對(duì)于this關(guān)鍵字的使用誤區(qū)。This指代的是什么?它和日常英語口語中的this是一個(gè)意思嗎?
隨著近些年js編程不斷地復(fù)雜化,功能多樣化,對(duì)于一個(gè)程序結(jié)構(gòu)的內(nèi)部指引、引用也逐漸變多起來
下面讓我們一起來看這一段代碼:
Game.prototype.restart = function () { this.clearLocalStorage();
this.timer = setTimeout(function(){ this.clearBoard(); }, 0);
};
運(yùn)行上面的代碼將會(huì)出現(xiàn)如下錯(cuò)誤:
Uncaught TypeError: undefined is not a function
這是為什么?this的調(diào)用和它所在的環(huán)境密切相關(guān)。之所以會(huì)出現(xiàn)上面的錯(cuò)誤,是因?yàn)楫?dāng)你在調(diào)用 setTimeout()函數(shù)的時(shí)候, 你實(shí)際調(diào)用的是window.setTimeout(). 因此,在 setTimeout() 定義的函數(shù)其實(shí)是在window背景下定義的,而window中并沒有 clearBoard() 這個(gè)函數(shù)方法。
下面提供兩種解決方案。第一種比較簡(jiǎn)單直接的方法便是,把this存儲(chǔ)到一個(gè)變量當(dāng)中,這樣他就可以在不同的環(huán)境背景中被繼承下來:
Game.prototype.restart = function () { this.clearLocalStorage();
var self = this;
this.timer = setTimeout(function(){ self.clearBoard();}, 0); };
第二種方法便是用bind()的方法,不過這個(gè)相比上一種要復(fù)雜一些,對(duì)于不熟悉bind()的同學(xué)可以在微軟官方查看它的使用方法:https://msdn.microsoft.com/zh-cn/library/ff841995
Game.prototype.restart = function () { this.clearLocalStorage();
this.timer = setTimeout(this.reset.bind(this), 0); };
Game.prototype.reset = function(){ this.clearBoard();};
上面的例子中,兩個(gè)this均指代的是Game.prototype。
更多建議: