获取警告不要在循环 jslint 中创建函数

Getting warning don't make functions within a loop jslint

我收到警告不要在我的代码循环中创建函数我正在使用 jslint 我的问题是

  1. 是否可以忽略此警告。
  2. 我该如何纠正这个问题。

jsfiddle link

/*global prompt,alert,console,rgb*/
/*jslint plusplus: true */
/*jshint loopfunc: true */
var colors = [
    'rgb(255, 0, 0)',
    'rgb(255, 255, 0)',
    'rgb(255, 255, 255)',
    'rgb(0, 255, 255)',
    'rgb(0, 255, 0)',
    'rgb(0, 0, 255)'
];

var pickedColor = colors[2];
var square = document.querySelectorAll(".square");
var i;
var colorMatch = document.querySelector(".pickedColor");
for (i = 0; i < square.length; i++) {
    //add different color to square
    square[i].style.background = colors[i];
    //add eventlistner to square
    square[i].addEventListener('click', function () {
        'use strict';
        var selectedColor = (this.style.background);
        if (selectedColor === pickedColor) {
            console.log("True");
        } else {
            console.log('False');
        }
    });
}
colorMatch.textContent = pickedColor;
body{
    background: rgb(52, 73, 94);
}
h1{
    color: white;
}
.container{
    margin: 0 auto;
    max-width: 600px;
}
.square{
    width: 30%;
    margin: 1.66%;
    background-color: purple;
    padding-bottom: 30%;
    float: left;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Color Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
   <h1>The Great <spam class="pickedColor"
   >RGB</spam> Color Game</h1>
   <div class="container">
       <div class="square"></div>
       <div class="square"></div>
       <div class="square"></div>
       <div class="square"></div>
       <div class="square"></div>
       <div class="square"></div>
   </div>
    <script src="script.js"></script>
</body>
</html>

同时,非常感谢您的关注和参与。

不要创建一个函数的几十个副本,而是创建一个并使用一个引用。

var square_listener = function() {
    var selectedColor = (this.style.background);
    if (selectedColor === pickedColor) {
        console.log("True");
    } else {
        console.log('False');
    }
}

for (i = 0; i < square.length; i++) {
    square[i].style.background = colors[i];
    square[i].addEventListener('click', square_listener);
}

出于性能原因,创建函数需要一些时间,所以如果不必多次(在循环中)完成,那就更好了。你可以在循环之前定义你的函数,在里面引用它:

function handler() {
        'use strict';
        var selectedColor = (this.style.background);
        if (selectedColor === pickedColor) {
            console.log("True");
        } else {
            console.log('False');
        }
    }

for (i = 0; i < square.length; i++) {
    //add different color to square
    square[i].style.background = colors[i];
    //add eventlistner to square
    square[i].addEventListener('click', handler);
}

在那个 特定的 案例中,您可以忽略警告,因为您的函数不使用它们关闭的任何变量(如 i)循环过程。

但是因为他们不这样做,所以没有理由创建该函数的多个副本,而只有一个就可以:

function squareClick() {
    'use strict';
    var selectedColor = (this.style.background);
    if (selectedColor === pickedColor) {
        console.log("True");
    } else {
        console.log('False');
    }
}

for (i = 0; i < square.length; i++) {
    //add different color to square
    square[i].style.background = colors[i];
    //add eventlistner to square
    square[i].addEventListener('click', squareClick);
}

哪里会出问题:

假设您这样做并且有 8 个方块:

for (i = 0; i < square.length; i++) {
    square[i].addEventListener('click', function() {
        alert(i); // <=== Using i
    });
}

当您单击这些方块时,无论您单击哪个方块,您都会看到值 8,因为这些函数有 实时引用 i变量,而不是变量创建时的副本。

这就是 jsLint 警告您的部分原因:要么您需要小心(因为您正在使用 i),要么在循环中创建函数毫无意义(因为您没有使用任何变化)。

最后说明:在 ES2015 中,您可以安全地执行此操作:

for (let n = 0; n < square.length; n++) {
    square[n].addEventListener('click', function() {
        alert(n); // <=== Using n
    });
}

...您会看到 0、1、2、... 7,具体取决于您单击的方块。这是因为 let 声明 within for 循环的 ES2015+ 语义专门设计用于确保每个循环迭代都获得自己的 n 副本.这与使用 var.

的看似几乎相同的版本非常不同

示例var;他们都显示 8:

var square = document.querySelectorAll(".square");
for (var i = 0; i < square.length; i++) {
  square[i].addEventListener('click', function() {
    alert(i); // <=== Using i
  });
}
<div class="square">zero</div>
<div class="square">one</div>
<div class="square">two</div>
<div class="square">three</div>
<div class="square">four</div>
<div class="square">five</div>
<div class="square">six</div>
<div class="square">seven</div>

let 示例(在兼容 ES2015+ 的浏览器上);他们显示 0...7:

var square = document.querySelectorAll(".square");
for (let n = 0; n < square.length; n++) {
  square[n].addEventListener('click', function() {
    alert(n); // <=== Using n
  });
}
<div class="square">zero</div>
<div class="square">one</div>
<div class="square">two</div>
<div class="square">three</div>
<div class="square">four</div>
<div class="square">five</div>
<div class="square">six</div>
<div class="square">seven</div>

请注意,let 必须 范围内 for 才能生效。也就是说,

let n;
for (n = 0; n < square.length; ++n)

非常不同
for (let n = 0; n < square.length; ++n)

就循环内创建的函数而言,前者的行为类似于 var。后者没有。