Задача 1
Закрытия связывают всю область действия функции, а не отдельные переменные или значения.
Возьмите этот код, например:
function foo() {
var i, func;
for (i = 0; i < 10; ++i) {
if (i == 0) {
func = function () {
alert(i);
}
}
}
func();
}
foo();
Вы можете ожидать foo
, чтобы 0
был предупрежден.Однако значение i
изменилось с момента создания функции, назначенной func
;вызов func
предупреждает «10».
Вот еще один пример, иллюстрирующий концепцию:
function foo() {
var i = 42;
function func() {
alert(i);
}
for (i = 0; i < 10; ++i) {
// do nothing
}
func();
}
foo();
Попробуйте выяснить, что будет предупреждено, и запустите код в качестве теста.
Задача 2
Вторая проблема заключается в том, что переменные связаны с областью действия функции (а не с областью блока, как вы ожидаете).
Возьмите этот код:
function foo() {
var i;
for (i = 0; i < 10; ++i) {
var j = i;
}
alert(j);
}
foo();
Вы можете ожидать, что этот код выдаст предупреждение «undefined», выдаст ошибку времени выполнения или даже выдаст ошибку синтаксиса.Тем не менее, «10» предупрежден.Зачем?В JavaScript приведенный выше код эффективно транслируется:
function foo() {
var i;
var j;
for (i = 0; i < 10; ++i) {
j = i;
}
alert(j);
}
foo();
Из этого примера должно быть более ясно, что «10» действительно предупрежден.
Решение
Итаккак вы решаете свою проблему?Самый простой способ - изменить свою логику: вместо того, чтобы прикреплять один обработчик событий на собаку, атакуйте одного обработчика событий на коллекцию собак.Например:
function blah(json) {
$('#puppy').click(function () {
var u, dog;
for (u = 0; u < json[0][1][u].length; u++) {
dog = 'k' + json[0][1][u].doggies;
console.log(dog);
$('#' + dog).css('display', 'none');
}
});
}
Если вас интересует «правильное» преобразование существующего кода (т. Е. Такое же поведение, за исключением исправленной ошибки), я могу привести пример этого какЧто ж.Однако решение, которое я дал выше, является намного лучшим решением и приводит к более чистому коду.