I'm reading the Mozilla developer's site on closures, and I noticed in their example for common mistakes, they had this code:
<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);
}
}
}
and they said that for the onFocus event, the code would only show help for the last item because all of the anonymous functions assigned to the onFocus event have a closure around the 'item' variable, which makes sense because in JavaScript variables do not have block scope. The solution was to use 'let item = ...' instead, for then it has block scope.
However, what I wonder is why couldn't you declare 'var item' right above the for loop? Then it has the scope of setupHelp(), and each iteration you are assigning it a different value, which would then be captured as its current value in the closure... right?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…