遇到Mozila developer network中描述的关闭常见错误
it doesn't work as expected. No matter what field you focus on, the message about your age will be displayed.
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);
}
}
}
setupHelp();
它确实给出了解决方案。这是添加另一个闭包。
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function makeHelpCallback(help) {
return function() {
showHelp(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 = makeHelpCallback(item.help);
}
}
setupHelp();
MDN给出的解释是因为第二种方案创建了3个环境。
谁能给我解释一下,“环境”阶段是什么意思,以及我如何知道它的范围?
最佳答案
当您在函数中使用变量名称时,JavaScript 解释器首先检查该变量是否为函数内的局部变量。如果不存在这样的局部变量,则它会向上遍历到外部作用域以查找该变量。 (定义函数时,它可以访问作用域链——作用域的层次结构,从定义该函数的外部函数的作用域开始,一直到包含该函数的函数等)
这里,匿名onfocus
处理函数使用变量标识符item
。 item
不是函数内的局部变量,因此当执行处理程序时,JavaScript 必须向上遍历下一个外部作用域,在其中找到 item
(如 中定义)安装帮助
。您为每个项目定义了一个处理函数;然而,这些处理函数的所有都在外部作用域中持有对item
的相同引用。每当调用这些函数中的任何一个时,JavaScript 都会为 item
查找相同的值,该值是 for
循环完成时它所保存的值。
如果有额外的闭包,您可以将 item.help
的当前值作为参数传递给 makeHelpCallback
,后者返回一个处理函数。由于 JavaScript 按值传递变量,因此每个处理函数现在都有一个单独的外部作用域,并具有不同的 help
值。
关于javascript - javascript 闭包中的环境范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14114521/