Javascript 有关闭问题。Can';我似乎无法解决它。请告知

Javascript 有关闭问题。Can';我似乎无法解决它。请告知,javascript,prototypejs,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', (fu

我有以下代码:

  _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.单击链接
因为您要将
作为参数传入,您只需要为它创建一个参数-调用它,比如说,
\u this
-然后您可以在函数中引用
\u this
,而不是
this

                (function(_this, innerkey){
                  $(innerkey).observe('click', (function(e){
                    Event.stop(e);
                    someClass.click_link( _this.items.sublinks[key][innerkey],false)
                   }));
                 )(this, innerkey);
(还有其他的方法,但上面的方法似乎就是你在把
这个
作为一个参数传入时所采用的方法?这是一种非常体面的方式。)


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

由于您将
作为参数传入,您只需为其创建一个参数-调用它,例如,
\u this
-然后您可以在函数中引用
\u this
,而不是
this

                (function(_this, innerkey){
                  $(innerkey).observe('click', (function(e){
                    Event.stop(e);
                    someClass.click_link( _this.items.sublinks[key][innerkey],false)
                   }));
                 )(this, innerkey);
(还有其他的方法,但上面的方法似乎就是你在把
这个
作为一个参数传入时所采用的方法?这是一种非常体面的方式。)

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

对“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;
            }
        }
    }
}
对“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;
            }
        }
    }
}

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

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,但我发现这种方式更具可读性。

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

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,但我发现这种方法更具可读性。

不要忘记
innerKey
变量。@RobW:对,它可以在闭包实际运行时更改它所指的内容。好的一点,我会解决的;谢谢!不要忘记
innerKey
变量e、 @RobW:是的,当关闭真正运行时,它可能已经改变了它所指的内容。很好,我会解决的,谢谢!