2013-07-30 25 views
6

Secrets of Javascript Closures,司徒Langridge呈現的代碼來演示在.onclick回調封閉的共同使用的一個片段,並轉述:如何使用Object.prototype.bind()重新實現'var that = this'來保存範圍引用?

link.onclick = function (e) { 
    var newa = document.createElement("a"); 
    var that = this; 
    document.body.appendChild(newa); 
    newa.onclick = function (e) { 
     that.firstChild.nodeValue = "reset"; 
     this.parentNode.removeChild(this); 
    } 
} 

我最近偶然發現了凱爾辛普森一家議長甲板New Rules For Javascript和他提到將this的範圍保存爲var self = this或(如片段中所示)var that = this這樣的封閉是「誤導」的,並且是Object.prototype.bind()的情況。除了ES5兼容性外,我更傾向於傾聽語言結構來解決問題,而不是使用黑客或快速修復,但在此代碼段中,使用bind,applycall的問題是,對包含值this並且需要關閉的參考值this

這是一個實用性勝過哲學的例子嗎?可以做什麼?

+4

在像你需要兩個參考你的情況下,我認爲你不能避免存儲實例的引用。如果它讓你覺得任何更清潔的東西,你可以將外部實例作爲參數傳遞給包裝內部函數的自調用匿名函數,但在語義上,這將是相同的。 – xbonez

+0

我已經看到過以前使用過的,並且從描述中可以明白爲什麼使用它:使用閉包來保存引用範圍的狀態。你是對的,它在語義上是相同的,但由於某種原因,只是感覺_better_,儘管我可以對原始類的一流功能進行某種沙文主義! – lintuxvi

回答

1

我不會認爲你的例子是bind這個錯誤的情況,這是單獨的引用。對於綁定一個被誤導的情況是:

var that = this; 

var fn = function() { 
    that.method(); 
} 

return fn; 

VS

var fn = function() { 
    this.method(); 
} 

return fn.bind(this); 
+0

我認爲這總結了該經驗法則的範圍 – lintuxvi

3

在一般情況下,如果您確實需要thisthat,那麼您不能只廢除其中一個,對嗎?

在點擊處理程序的情況下,您應該能夠通過查看傳入的事件對象來獲取有問題的元素。我相信它具有某種target屬性。所以你可以用e代替this,然後綁定得到that作爲this

根據頁面結構的不同,您也可以遍歷DOM從thisthat,特別是如果您使用id或class在語義上標記事物。

+0

據我所知,我完全同意。這個例子看起來像是一個保存'this'引用的實際案例。優選地,從回調的事件參數引用'parentNode'似乎在這種情況下是更好的參考。也許關鍵的是:代碼中的上下文勝過經驗法則。 – lintuxvi

相關問題