循环内的 JavaScript 函数

标签 javascript function jslint

谁能用这个例子向我解释为什么 JSLint 提示“循环内的函数”:

  for (var i = 0; i < buttons.length; i++) {
    (function(i) {
      buttons[i].onclick = function(e) {
        t.progressBars[t.current].update(buttons[i].getAttribute("data-value"));
      }
    })(i);
  }

但是当我把它改成:

function makeHandler(i)
  {
    return function() {
        t.progressBars[t.current].update(buttons[i].getAttribute("data-value"));
      }
  }

  for (var i = 0; i < buttons.length; i++) {

      buttons[i].onclick = makeHandler(i);

  }

我不太明白,因为似乎每次循环迭代都必须返回新的函数对象,即使它发生在 makeHandler() 函数内部。为什么第二个示例适用于 JS linters?

最佳答案

引自linterrors ,

var elems = document.getElementsByClassName("myClass"), i;
for (i = 0; i < elems.length; i++) {
    (function (iCopy) {
        "use strict";
         elems[i].addEventListener("click", function () {
            this.innerHTML = iCopy;
         });
    }(i));
}

What we have now captures the value of i at each iteration of the loop. This happens because JavaScript passes arguments to functions by value. This means that iCopy within the capturing function is not related to i in any way (except for the fact that they happen to have the same value at that point in time). If i changes later (which it does - on the next iteration of the loop) then iCopy is not affected.

This will work as we expect it to but the problem now is that the JavaScript interpreter will create an instance of the capturing function per loop iteration. It has to do this because it doesn't know if the function object will be modified elsewhere. Since functions are standard JavaScript objects, they can have properties like any other object, which could be changed in the loop. Thus by creating the function in the loop context, you cause the interpreter to create multiple function instances, which can cause unexpected behavior and performance problems. To fix the issue, we need to move the function out of the loop:

我希望在这里使用 Array.prototype.forEach,就像这样

buttons.forEach(function(curButton) {
    curButton.onclick = function(e) {
        t.progressBars[t.current].update(curButton.getAttribute("data-value"));
    };
});

关于循环内的 JavaScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26154150/

相关文章:

javascript - 显示 onclick 函数后从数据库检索的推文

javascript - 使用 bootstrap 的表单设计 - 对齐文本框和文本区域

javascript - Node.js express : How to redirect page after processing post request?

c++ - 使用函数创建数组 - Objective-C++

javascript - 有什么工具可以自动修复简单的 JSLint 问题?

javascript - 前后空格 = 登录 javascript

javascript - 在 jQuery 对象数组上调用 show

python - 通过字符串名称执行函数

c++ - 如何避免从文件中读取错误的 '\n'?

javascript - JSLint 提示重新定义未定义