我正在学习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);
}
我对此代码感到困惑。在每个循环开始时声明的div对象发生了什么?这是一个全新的,单独的对象每次,不知何故被封闭在我的块范围内?或者这个div对象是否被覆盖,每次通过循环,如果是这样,它如何保持它与i的连接通过let给出?
答案 0 :(得分: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);
};
因为您使用let
来分配i
,所以它的值仅适用于每个循环迭代的循环范围(或Babel示例中的函数)。要获得div
变量的相同功能,可以在循环体中分配该变量。
for (let div, i = 0; i < 45; i++) {
div = document.createElement('div');
...
}
最后,关于闭包并保留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);
如果没有函数工厂,onClick
值将始终获得最大i
值44.这是因为函数在整个循环迭代后运行,i
具有停在i < 45
。
答案 1 :(得分:2)
<div>
在每次迭代中都是一个全新的对象,但不是包含在i
的块范围内。
附加到div
的函数表达式但是也是一个全新的对象,但此对象 正在关闭i
。
答案 2 :(得分:0)
每次迭代div
都是一个分支的新对象元素。
Let
定义i
只能在foreach
循环(What's the difference between using "let" and "var" to declare a variable?)内访问。
一旦div
元素被附加到“section”元素并且for循环开始一个新的迭代,你将丢失对最近附加的div的引用,用一个新的覆盖它。