2011-04-05 88 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