1

объясните пожалуйста доступно(не одним словом),почему у объекта x все 3 значения равны 3 а не 1 2 3 как я думаю .в следующем коде

function foo(){       
   var a =[ ];                        
   for(var i = 0; i < 3; I++)                                          
     a.push(function(){ print(i) } );                                          
   return a;
}  

var x=foo();
ArchDemon
  • 2,821
  • Про замыкание знаете? – Александр Aug 26 '18 at 17:37
  • замыкание это область видимости? – proximo28 Aug 26 '18 at 17:50
  • выразить ничего не хотел,это учебный материал – proximo28 Aug 26 '18 at 17:54
  • Что бы получилось то что хочешь, просто замени for(var ' var 'на 'let' – Air Aug 26 '18 at 17:54
  • я хочу понять откуда берется именно 3 3 3 x[0] x[1] x[2] – proximo28 Aug 26 '18 at 17:55
  • Потому что переменная/ссылка i не уникальная для каждого вызова, там адрес один и тот же, по этому будет доступно последнее установленное значение, полученное после выполнения цикла, всех его итераций. Нужно замыкание, что бы образовать специальную область видимости где будет хранится уникальное значение – Евгений Федак Aug 26 '18 at 18:07
  • 1
    спасибо.немогу оценить.репутации не хватает.) – proximo28 Aug 26 '18 at 18:09
  • Не обязательно замыкание, можно вместо var i = 0 писать let i = 0 – Илья Зелень Aug 26 '18 at 18:13
  • @Илья Зеленько,а что let i = 0 уже не замыкание? – Александр Aug 26 '18 at 18:15
  • В коде вопроса уже есть замыкание. let создает для каждой итерации свою локальную переменную. – Илья Зелень Aug 26 '18 at 18:19

2 Answers2

0

Что вы хотели в этом алгоритме выразить? В стек (массив по принципу стека) помещается три функции, с индексами {0, 1, 2} внутри которой находится вызов функции для печати, в которую передается одно и тоже значение! Внутри массива, можно вызвать нужный элемент, то есть функцию синтаксиса x[0](); Если необходимо передать уникальные значения, то требуется воспользоваться замыканиями. К примеру:

function foo() {
    var a = [];
    for(var i=0;i<3;i++)
        a.push((function(i){ return function() {
            console.log(i); 
        } })(i)); 
    return a;
} 
var x=foo();
x[0]();
x[1]();
x[2]();
0

Если нужно для каждой функции свой i, то можно вместо var i = 0; писать let i = 0;

function foo(){       
   var a =[ ];                        
   for(let i = 0; i < 3; i++)                                          
     a.push(function(){ return i } );                                          
   return a;
}

var x=foo();

for (el of x) console.log(el())

Вот детально объяснение проблемы и 3 варианта решения(варианта с let там нет, но так тоже можно): https://learn.javascript.ru/task/make-army