当我在循环中创建5个按钮并单击i的值总是6
function createButtons() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName("BODY")[0];
var button = document.createElement("BUTTON");
button.innerHTML = 'Button ' + i;
(function(num) {
button.onclick = function() {
alert('This is button ' + num);
}
})(i);
body.appendChild(button);
}
}
&#13;
但是当我将i的范围更改为阻止范围(使用IIFE或let关键字)时,它给出了正确的i值。它是如何在javascript引擎下工作的?
答案 0 :(得分:0)
我已将您的功能分为incorrect
和correct
一个。
incorrect
版本就是您所要求的。 correct
版本是您已经想到的,但不知道它为什么会起作用。
在错误的版本中,i
的值将始终更新为最新值,因为i
属于createButtons
函数,并与所有onclick
共享处理程序,它随着循环而改变。
在正确的版本中,i
的值会以num
的形式提供给IIFE,而num
属于IIFE,而不属于createButtons
。
因此,num
是固定的,因为为每个循环创建了一个新的num
,因此不会与另一个onclick
处理程序共享。
为什么呢?这是闭包在JavaScript中的工作方式。
Read this for deeper understanding on JavaScript closure.
function createButtons_incorrect() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName("BODY")[0];
var button = document.createElement("BUTTON");
button.innerHTML = 'Bad ' + i;
button.onclick = function() {
alert('This is button ' + i);
}
body.appendChild(button);
}
}
function createButtons_correct() {
for (var i = 1; i <= 5; i++) {
var body = document.getElementsByTagName("BODY")[0];
var button = document.createElement("BUTTON");
button.innerHTML = 'Good ' + i;
(function(num){
button.onclick = function() {
alert('This is button ' + num);
}
})(i);
body.appendChild(button);
}
}
createButtons_incorrect();
document.body.appendChild(document.createElement('br'));
createButtons_correct();