我正在阅读 Mozilla 开发者网站上有关闭包的内容,我注意到在他们的常见错误示例中,他们有以下代码:
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
and
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
他们说,对于 onFocus 事件,代码只会显示最后一项的帮助,因为分配给 onFocus 事件的所有匿名函数都有一个围绕“item”变量的闭包,这是有道理的,因为在 JavaScript 中变量没有块范围。解决方案是使用“let item = ...”来代替,因为这样它就有了块作用域。
但是,我想知道为什么你不能在 for 循环上方声明“var item”?然后它具有 setupHelp() 的范围,并且每次迭代都为它分配一个不同的值,然后该值将被捕获为闭包中的当前值......对吗?
其原因在于当时item.help
被评估后,循环将完全完成。相反,您可以通过闭包来做到这一点:
for (var i = 0; i < helpText.length; i++) {
document.getElementById(helpText[i].id).onfocus = function(item) {
return function() {showHelp(item.help);};
}(helpText[i]);
}
JavaScript 没有块作用域,但有函数作用域。通过创建一个闭包,我们捕获了对helpText[i]
永久。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)