#javascript #loops #closures
Вопрос:
1.Пример MDN
Приведенный ниже фрагмент кода назначает функцию, отображающую текст справки для каждого текстового поля при фокусировке, вот ссылка на JsFiddle: https://jsfiddle.net/v7gjv/8164/
function showHelp(help) {
document.getElementById('help').textContent = 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();
Но он будет отображать только последний текст справки, независимо от того, какой из трех входных данных сфокусирован. MDN говорит, что функция, назначенная всем трем входам, является закрытием, поэтому они используют одну и ту же ссылку на переменную HelpText, когда цикл заканчивается, i=2, поэтому все три входа имеют ссылку на последний элемент в HelpText.
2.My испытание
Часть, в которой я не понимаю, заключается в том, почему все три входа имеют одинаковую ссылку на один и тот же элемент переменной, я провожу такой тест
(function() {
function closure() {
var i = 0;
return {
display: function() {
console.log(i);
},
add: function() {
i = 1;
}
}
}
var a = closure();
var b = closure();
a.add();
a.display(); //return 1
b.display(); //return 0
})()
3.My мысли и вопросы
Из теста a и b имеют разные переменные i, i из a изменился, но b остался прежним. Но в цикле for все входные данные указывают на одну и ту же переменную, поэтому цикл for изменяет значение i, в результате чего все входные данные указывают на последний элемент в справочном тексте
Поэтому мой вопрос в том,почему они указывают на одну и ту же переменную, но в моем тесте a, b этого не делают.
Комментарии:
1. «но в моем тесте a,b этого не делают» , потому
i
что определено внутри функции, но в примере MDNitem
определено вне обработчика событий.2. Я действительно не понимаю, я понимаю,что onfocus-это одно из свойств элемента {…, onfocus:функция(){}} это верно ?
3. Да, функция назначается свойству, но на самом деле это не важно. Важно то, что функция обращается к свободной переменной (переменной, которая сама по себе не определена), и функция вызывается после завершения цикла. Вы добьетесь того же поведения, если переместите
var i = 0;
объявление за пределыclosure
функции.
Ответ №1:
В вашем примере вы объявляете переменную i
внутри closure
метода. При повторном вызове closure
i
в области выполнения этой конкретной функции создается новая переменная, и возвращаемый объект привязывается к этой переменной.
Попробуйте переместить объявление переменной за пределы closure
функции, и вы увидите, что результат будет таким же, как в примере MDN.
Комментарии:
1. Теперь я думаю об этом, функция доступа к глобальной переменной-довольно базовая функция, просто другой язык не может назначить функцию, такую как javascript
2. @khuongduy354: На самом деле существует множество языков, в которых функции являются объектами первого класса . Но даже на этих языках закрытие может работать по-другому.