让关键字和关闭?

use*_*853 5 javascript ecmascript-6

我正在学习ES6中的新功能.我有关于let的问题,它关注此代码:

for (let i = 0; i < 45; i++) {
    var div = document.createElement('div');
    div.onclick = function() {
        alert("you clicked on a box #" + i);
    };
    document.getElementsByTagName('section')[0].appendChild(div);
}
Run Code Online (Sandbox Code Playgroud)

我对此代码感到困惑.在每个循环开始时声明的div对象发生了什么?这是一个全新的,单独的对象每次,不知何故被封闭在我的块范围内?或者这个div对象是否被覆盖,每次通过循环,如果是这样,它如何维持它与i的连接是通过let给出的?

Rya*_*yan 5

当我想更好地了解ES6代码中发生的事情时,我将我的Javascript输入BabelJS REPL.

输入REPL输出时的代码:

'use strict';

var _loop = function (i) {
  div = document.createElement('div');

  div.onclick = function () {
    alert("you clicked on a box #" + i);
  };

  document.getElementsByTagName('section')[0].appendChild(div);
};

for (var i = 0; i < 45; i++) {
  var div;

  _loop(i);
};
Run Code Online (Sandbox Code Playgroud)

因为您曾经let分配过i,所以它的值仅在每个循环迭代的循环范围(或Babel示例中的函数)中可用.要获得div变量的相同功能,可以在循环体中分配该变量.

for (let div, i = 0; i < 45; i++) {
  div = document.createElement('div');
  ...
}
Run Code Online (Sandbox Code Playgroud)

最后,关于闭包和保持i变量,您距离创建闭包以保持i每个变量的当前值只有一步之遥div.

// Create a function to hold on to a specific number
function createOnClick(index) {
  return function() {
    alert("you clicked on a box #", index);
  };
};

// Assign the function to the element's action 
div.onClick = createOnClick(i);
Run Code Online (Sandbox Code Playgroud)

如果没有函数工厂,该onClick值将始终获得最大值i44.这是因为函数在整个循环迭代并且i已停止后运行i < 45.