【问题标题】:How to prevent function in a loop如何防止循环中的功能
【发布时间】:2013-06-17 15:06:28
【问题描述】:

我有一个像这样在 for 循环中声明的 jquery click 函数

for (i = 1; i !== 4; i += 1) {
    id = "index" + i + "id";
       if ($(id).length) {
          $(id).click(function() {
             var isChecked = this.checked;
             onclickHelper(isChecked, this.id);
          });
       }
}

如何摆脱在循环中创建函数的警告?第二个为什么不好(jslint 给了我这个警告)

【问题讨论】:

  • 为我们提供更多代码将帮助我们解决问题。此外,您可能想要调用函数而不是将块放在 IF 中。
  • if ($(id).length) 毫无意义
  • 嗨,感谢 if 循环是检查元素是否存在

标签: jquery for-loop jslint


【解决方案1】:
var $ids = $();
for (var i = 1; i < 4; i++)
    if($("#index" + i + "id").length)
        $ids = $ids.add("#index" + i + "id");

$ids.click(function () {
    var isChecked = this.checked;
    onclickHelper(isChecked, this.id);
});

【讨论】:

  • 如何知道id是否存在?
【解决方案2】:

尝试这样的不循环,

$("[id=^'index']").click(function() {
     var isChecked = this.checked;
     onclickHelper(isChecked, this.id);
});

【讨论】:

    【解决方案3】:

    SLaks 是正确的,遵循该建议的最小重构(不具体讨论这里发生的事情的优点)如下所示:

    /*global $, onclickHelper */
    var i, id, fnCached;
    
    // cache your function instead of creating each time in your loop
    fnCached = function() {
        var isChecked = this.checked;
        onclickHelper(isChecked, this.id);
    };
    
    for (i = 1; i !== 4; i += 1) {
        id = "index" + i + "id";
        if ($(id).length) {
            $(id).click(fnCached());  // then simply call it
        }
    }
    

    正如他所说,JSLint 只是希望您更有效地运行事物,并且由于您可以将函数缓存在变量中,在循环之外但在相同的范围内声明,poof,您就完成了。

    巧妙的是,“因为”提升,如果您在函数中使用 i 并在循环之前声明 fnCached,则上下文“移动”就像您声明循环一样,所以这种快速缓存技巧几乎总是有效的(尽管如果声明更进一步的范围确实有意义,那就去做吧)。

    /*jslint browser: true */
    this.spam = "spam";
    
    var i, fnCached;
    
    fnCached = function () {
        // i's scope pervades the snippet here
        window.alert(this.spam + " " + i);
    };
    
    for (i = 0; i < 3; i += 1) {
        fnCached();
    }
    

    这样会提醒“垃圾邮件 0”、“垃圾邮件 1”和“垃圾邮件 2”。

    Fiddle

    【讨论】:

      【解决方案4】:

      每次执行表达式function() { ... }(我不是指调用函数)时,Javascript 都会为函数创建一个单独的闭包。
      这会不必要地浪费内存。

      它还会诱使您犯错误,例如在函数中使用 i(由于 Javascript 没有块作用域,这不会按您期望的方式工作)。

      相反,您应该将函数放在循环之外——只创建一次,并将其存储在一个变量中——然后将相同的函数实例添加到每个元素。

      【讨论】:

      • 实际上,i 可以在函数中工作——即使你按照 JSLint 想要的方式缓存它。请参阅Fiddle 来自答案below
      • @ruffin:是的,但如果你在循环之后调用它(例如,从事件处理程序)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      相关资源
      最近更新 更多