简体   繁体   English

作用域如何在for循环中工作?

[英]How scope works in a for loop?

When I created 5 buttons in a loop and click the value of i is always 6 当我在循环中创建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); } } 

but when I change the scope of i to block scope(using IIFE or let keyword) it gives the right value of i. 但是,当我将i的范围更改为块范围(使用IIFE或let关键字)时,它会给出i的正确值。 How does it working under the hood of javascript? 如何在javascript的背景下工作?

I have seperated your functions into incorrect and correct one. 我已将您的功能分为incorrectcorrect功能。

The incorrect version is what you're asking. 您要求的版本incorrect The correct version is what you've already figured out but don't know why it work. correct版本是您已经想出的,但是不知道它为什么起作用。

In the incorrect version, the value of i will always be updated to the most recent value because i belongs to the createButtons function and is shared with all onclick handler, and it is changing with the loop. 在不正确的版本中, i的值将始终更新为最新值,因为i属于createButtons函数并与所有onclick处理程序共享,并且它随循环而变化。

In the correct version, the value of i is given to the IIFE as num , and num belongs to the IIFE and not to createButtons . 在正确的版本中, i的值以num形式提供给IIFE,而num属于IIFE而不是createButtons

Because of that, num is fixed because a new num is created for every loop thus is not shared with the other onclick handler. 因此, num是固定的,因为会为每个循环创建一个新的num ,因此不会与其他onclick处理程序共享。

Why? 为什么? It is how closure works in JavaScript. 这就是JavaScript中闭包的工作方式。

Read this for deeper understanding on JavaScript closure. 阅读此书可以更深入地了解JavaScript的关闭。

 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(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM