2013-04-11 83 views
3

我有一個關於在一個對象中維護this的範圍的一般性問題。這裏有一個簡單的代碼片段。請注意0​​一行,並在事件處理程序中呼叫that.showMenu()維護範圍

var MyObj = { 
    init : function(target){ 
     this.$Target = $(target); 
     this.$Menu = $(target).find('.menu'); 
     this.eventBindings(); 
    }, 
    eventBindings : function(){ 
     var that = this; 
     this.$Target.on('click', '.anchor', function(e){ 
      e.preventDefault(); 
      that.showMenu(); 
      //some other code 
     }); 
    }, 
    showMenu : function(){ 
     this.$Menu.show(); 
    } 
}; 
MyObj.init('.myTarget') 

代碼應該有點自我解釋。通常我會嘗試在我的eventBindings()之外創建可重用的方法。我不斷遇到的問題是通過this,這將參考MyObj到事件處理程序,所以我可以撥打this.showMenu()

爲了克服障礙,我總是將this分配給一個名爲that的變量,所以當我進一步縮小範圍時,我有一個參考。但我覺得這不可能是最好的方法...有人可以提出更好的選擇嗎?

+0

對我來說看起來很好,但'那是一個可怕的名字。考慮一些更具描述性的內容,比如'outerScope'。 – 2013-04-11 21:27:23

+0

另請參閱函數原型上的[.bind()'方法](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind)。 – Pointy 2013-04-11 21:28:03

+0

@RobertHarvey儘管如此,多年來這種'這個'是如何被普遍使用的,這不是很有趣嗎? ;) – summea 2013-04-11 21:53:50

回答

1

你在做什麼是最好的方法。在Javascript中,this是動態範圍的(綁定依賴於堆棧,位於函數被調用的位置),所有其他變量 - 靜態地進行作用域範圍(綁定取決於代碼中靜態放置變量)。

而且由於Javascript以特殊的方式對待this,所以不要以特殊的方式對待它。

你可以將你現在正在做的事情封裝在一個函數中 - 許多庫提供了這樣的工具,它通常被稱爲「綁定」。但是這不會改變真正發生的事情,只會隱藏它(並在做這件事時耗盡一些資源)。這樣的功能可能看起來有點像:

function whatever (functionToProcess, thisToFreeze) { 
    return function() { 
     functionToProcess.apply(thisToFreeze, arguments); // apply is built in 
    } 
} 
+0

太棒了 - 感謝您提供的信息。我會更多地瞭解綁定,但一般的共識是,我使用的方法是可以接受的,所以我不會試圖強調它太多。 – Syon 2013-04-11 21:58:56

0

繼@尖尖的評論,使用Function.prototype.bind

onClick: function(e){ 
     e.preventDefault(); 
     this.showMenu(); 
     //some other code 
    }, 
    eventBindings : function(){ 
     this.$Target.on('click', '.anchor', this.onClick.bind(this)); 
    }, 
0

你可以在把它作爲事件數據:

this.$Target.on('click', '.anchor', {obj:this}, function(e){ 
    e.preventDefault(); 
    e.data.obj.showMenu(); 
    //some other code 
}); 

或將它儲存的元素,但也不是真的有什麼不同的是外面聲明另一個變量一樣你是。