有一个关闭问题。似乎无法解决它。请指教

时间:2012-03-23 21:49:51

标签: javascript prototypejs

我有这段代码:

  _trackit: function(){
  for(var key in this.items.sublinks){
     switch(key){
         case 'shoes':
            for(var innerkey in this.items.sublinks[key]){
                (function(){
                  $(innerkey).observe('click', (function(e){
                    Event.stop(e);
                    someClass.click_link( this.items.sublinks[key][innerkey],false)
                   }));
                 )(this);
            }  
         break;
     }
  }
 }

我传入的哈希值大小为2.但正如你猜测这两个链接(因为哈希映射到链接),传递最后一个哈希值来通过(someClass.click_link< - 在这里这个值,this.item.sublinks[key][innerkey])。

我尝试过使用内部诱惑等......但有些事情搞得一团糟。如果我转到“内部函数深度”,则this.items会返回undefined

任何帮助?

3 个答案:

答案 0 :(得分:2)

由于你将this作为参数传递,你只需要为它创建一个参数 - 称之为_this - 然后你可以参考_this而不是函数内的this

                (function(_this, innerkey){
                  $(innerkey).observe('click', (function(e){
                    Event.stop(e);
                    someClass.click_link( _this.items.sublinks[key][innerkey],false)
                   }));
                 )(this, innerkey);

(还有其他方法,但上面似乎是你以this作为参数传递时的方式?而且这是一种非常值得尊敬的方式。)

编辑添加:根据Rob W的评论,我已编辑上述内容以添加innerkey作为参数,否则内部function(e){...}表达式将引用与外部函数相同的innerkey 变量 - 一个变量,它作为循环变量,可能在内部函数实际运行时发生变化。将其作为参数传递给内部表达式一个新的innerkey变量,该变量等于创建内部函数时innerkey 的变量。

答案 1 :(得分:1)

第二次调用“this”引用了被点击的实际元素。将其更改为:

_trackit: function () {
    var self = this;
    for (var key in this.items.sublinks) {
        switch (key) {
        case 'shoes':
            for (var innerkey in this.items.sublinks[key]) {
                (function () {
                    $(innerkey).observe('click', (function (e) {
                        Event.stop(e);
                        someClass.click_link(self.items.sublinks[key][innerkey], false)
                    }));)(this);
                }
                break;
            }
        }
    }
}

答案 2 :(得分:1)

正如其他人提到的,你需要有一个参数来接收你传递的“这个”。您还需要传递“key”和“innerkey”变量的副本,以避免for循环中的闭包bug。

var make_event_listener = function(that, key, innerKey){
    return function(e){
        Event.stop(e);
        someClass.click_link( that.items.sublinks[key][innerkey], false)
    };
};

//...
for(var innerkey in this.items.sublinks[key]){
   $(innerkey).observe('click', make_event_listener(this, key, innerKey) );
}
//...

当然,您可以使用匿名版本的make_event_listener,但我发现这种方式更具可读性。