Я уверен, что здесь делаю что-то немое, но я не уверен, что. Я добавляю анонимные функции в массив для последующего выполнения и создаю их в цикле for с переменными, которые меняют каждую итерацию.
Я ожидаю, что зарегистрированные значения будут такими: https: server.net/a https: server.net/b
но вместо этого я получаю: https: server.net/b https: server.net/b
Похоже, что когда я переопределяю функцию, она перезаписывает последнюю версию, но я не уверен, почему. Я бы подумал, что каждая анонимная функция будет отличаться.
Зачем? Что я здесь делаю неправильно?
Вот пример кода:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = 'https://server.net/${itemID}';
var func = function(){
console.log(itemAccessUrl);
};
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
func();
}
Это связано с природой var
varoping. var
не является блочным областью, он "поднимается", как если бы вы объявили его в верхней части своей функции.
Вы можете объявить itemAccessUrl, используя let
вместо var, который является блочным областью, но зависит от того, какую поддержку браузера вы требуете. (Сказав это, вы используете шаблонные строки, так что вы должны быть в порядке)
f[j]();
, В противном случае, вы будете вызывать одну и ту же функцию, всего несколько раз в цикле
Что здесь происходит? Когда вы вызываете свои функции массива, они используют текущее значение itemAccessUrl
, то есть последнюю назначенную строку, с char 'b'. Это происходит потому, что их вызов происходит после завершения первого цикла for.
Вы можете использовать закрытие:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = 'https://server.net/${itemID}';
var func = (function(param) {
return function () {
console.log(param);
};
})(itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
или привязать вашу функцию к текущему параметру:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = 'https://server.net/${itemID}';
var func = (function (param) {
console.log(param);
}).bind(null, itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
Кроме того, вам нужно изменить второй цикл, вызвав f[j]();