Разберите семантику и побочные эффекты в JavaScript: var a = []; for (var i=0;ii; } console.log(a[0](), a[1](), a[2]()); Какое поведение ожидается и как его исправить без ES6 let
Поведение: из‑за того, что varvarvar имеет функциональную (не блочную) область видимости, все стрелочные функции замыкают одну и ту же переменную iii. После цикла значение iii равно 333, поэтому все вызовы вернут 333. То есть вывод будет 3,3,33,3,33,3,3. Почему: в коде for (var i=000; i<333; i++){ a[i]=()=>i; } функции создаются с ссылкой на переменную iii, а не на её текущее значение. Исправления без ES6 letletlet: 1) IIFE (немедленно вызываемая функция), захватывающая текущее значение: for (var i=000; i<333; i++){ a[i] = (function(j){ return function(){ return j; }; })(i); } Теперь вызовы вернут 0,1,20,1,20,1,2. 2) Вспомогательная фабрика: function makeGetter(j){ return function(){ return j; }; } for (var i=000; i<333; i++){ a[i] = makeGetter(i); } Обе версии создают новую переменную jjj для каждой итерации, которую замыкает соответствующая функция.
Почему: в коде
for (var i=000; i<333; i++){ a[i]=()=>i; }
функции создаются с ссылкой на переменную iii, а не на её текущее значение.
Исправления без ES6 letletlet:
1) IIFE (немедленно вызываемая функция), захватывающая текущее значение:
for (var i=000; i<333; i++){
a[i] = (function(j){ return function(){ return j; }; })(i);
}
Теперь вызовы вернут 0,1,20,1,20,1,2.
2) Вспомогательная фабрика:
function makeGetter(j){ return function(){ return j; }; }
for (var i=000; i<333; i++){
a[i] = makeGetter(i);
}
Обе версии создают новую переменную jjj для каждой итерации, которую замыкает соответствующая функция.