изменение:
newdiv.ondblclick = function() {alert(items[i])}
к этому:
newdiv.ondblclick = (function(item) { return function() {alert(item)} })(items[i])
Посмотрите вверх Затворы , и это то, что вас портит в этом случае. Когда вы создаете анонимную функцию, используя function() { }
, вы создаете замыкание, которое связано с областью, в которой она была создана. Итак, внутри вашего замыкания ваша переменная i
- это та же переменная, которую вы использовали в цикле. Поэтому, когда вы дважды щелкнете по элементу, цикл уже закончен и i == 12
. Это было бы так же, как если бы вы поместили alert(i);
непосредственно после вашего for(i in items) { }
цикла.
Итак, учитывая это, как мой второй пример исправляет это?
Ну, он использует самозапускающуюся анонимную функцию, которая принимает одну переменную, item
. Эта функция возвращает замыкание, которое ограничено внутри ее области видимости. Внешнее закрытие немедленно выполняется, передавая items[i]
, что создает стабильную область видимости для переменной, в которой вы хотите жить.
Замыкания могут быть немного изнурительными, если вы к ним не привыкли, но понимание их - важная часть для получения функционального программирования с использованием JavaScript.
SetAttribute работает, потому что вы создаете новую строку, которая оценивает каждый раз в цикле, вместо поздней ссылки на переменную i
.
PS
Вероятно, плохая идея использовать for( in ) {}
в массиве. Вы можете получить неожиданные результаты, он должен перебирать все свойства объекта, а не только элементы в массиве. вероятно, безопаснее использовать обычный for(var i=0;i<items.length;i++) {}