2011-04-05 97 views
1

我有這個js:麻煩與JS關閉

(function() { 

    Namespace = { 

     settings: { 
      myVar: 'test' 
     }, 

     init: function() { 

      var memberSearchFrm = document.getElementById('memberSearch'); 
      memberSearchFrm.onsubmit = function() { 

       this.someOtherFunction(); // doesn't work 
       console.log(this.settings.myVar); // doesn't work 
      } 
     }, 

     someOtherFunction: function() { 
      console.log('test'); 
     } 
    } 

    Namespace.init(); 
})(); 

我失去的情況下「本」當我進入我的onsubmit功能。你能幫我理解爲什麼會發生這種情況,以及如何解決這種情況?

回答

3

試試這個技巧。

在關閉之前,爲此設置一個名爲'that'的變量。

var that = this; 

然後在你的閉包中使用它。你遇到的問題是閉包是連接到你的DOM節點而不是你的對象。所以當你調用閉包的時候,這有DOM節點的值。

+1

我不會用這個詞*伎倆*爲 – KooiInc 2011-04-05 17:28:20

+0

我建議稱之爲'self'。 – 2011-04-05 17:29:55

+0

我也更喜歡自我,但我認爲'那是一種更像Java的解決方案,每個人都希望JavaScript成爲Java。 – babsher 2011-04-05 17:33:19

3

裏面memberSearchFrm.onsubmit,this是指memberSearchFrm,而不是你想要的對象。您需要保存對this的引用。

init: function() { 
     var that = this; 
     var memberSearchFrm = document.getElementById('memberSearch'); 
     memberSearchFrm.onsubmit = function() { 
      that.someOtherFunction(); 
      console.log(that.settings.myVar); 
     } 
    }, 
1

我遇到了同樣的問題與閉包,並使這個小提琴嘗試不同的方式來調用閉包中的其他函數。

http://jsfiddle.net/7FzEz/5/

我終於用這種格式解決:

(function() { 

    var obj = { 

     settings: { 
      myVar: 'test' 
     }, 

     init: function() { 

      var memberSearchFrm = document.getElementById('memberSearch'); 
      memberSearchFrm.onsubmit = function() { 

       obj.someOtherFunction(); 
       console.log(obj.settings.myVar); 
      } 
     }, 

     someOtherFunction: function() { 
      console.log('test'); 
     } 
    } 

    obj.init(); 
})(); 
+0

命名空間只是我的示例中使用的佔位符名稱。 var給予它什麼好處?它可以用任何方式,j/c ... – doremi 2011-04-05 17:37:24

+0

其實,你的情況沒有,因爲你在匿名包裝,我會在這裏編輯它。當你不在匿名包裝中時,它很重要 - 請參閱範圍下的全局變量的禍害:http://bonsaiden.github.com/JavaScript-Garden/#function.scopes – 2011-04-05 17:43:13

+0

現在我回過頭來,將var確實有所作爲,因爲它可以防止污染你的全局名稱空間:http://jsfiddle.net/vtPuE/ – 2011-04-05 17:49:00