Замыкания в цикле
Здравствуйте. Помогите разобраться с такой проблемой. Есть код:
for(var i = 0; i <= 5; i++){ setTimeout () {function(){ console.log(i) }, i*1000} } 1. Почему когда происходит выполнение кода, в консоль записывается 5 шестерок, а тайм-аут срабатывает именно каждую секунду? Тут вопрос не про вывод на консоль шетерок, а именно работа тайм-аута. Каким образом секунда увеличивается постепенно, если логически, после выполнения цикла, вместо i * 1000 должно подставиться 6 * 1000? Следующий код: for(var i = 0; i <= 5; i++){ (function(){ var j = i; setTimeout () {function(){ console.log(j) }, j*1000} }()) } 2. Почему при таком варианте, каким-то образом каждая итерация запоминается в переменную j? Я понимаю что это замыкание и тайм-аут видит по замыканию сохраненной значение в переменной j каждый раз. Но вот как это происходит? Вот цикл завершился и записал в j шестерку. А как тайм-аут запомнил, что там были числа 0,1 и т.д.? Или тут работает отложенный вызов или какой-то стек создается? Тоесть сначало в j присваивается 0 а затем подставляется в тайм-аут функцию и она выполняется и так далее. Но ведь цикл завершается гораздо быстрее чем 1 секунда. Помогите разобраться. |
Цитата:
потому что переменная i одна на весь код, и каждом таймере одна и таже, со значением на момент окончания for Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
var j = i; j получила значение(число в данном случае) переменной i, но знать не знает о переменной i. в первом варианте идет ссылка на саму переменную, а не на её значение, какое значение имеет i на момент вывода консоли, то и покажет. может чем поможет, Пример ошибочного использования |
Цитата:
for(var i = 0; i <= 5; i++){ setTimeout(function() { console.log(i) }, i * 1000); } Цитата:
|
Цитата:
|
я на собеседованиях люблю "охладить пыл" собеседующих вот таким вариантом :)
for(var i = 0; i <= 5; i++){ setTimeout(function(i) { console.log(i) }, i * 1000, i); } |
let v = 4 // примитив let w = { v: 4 } // объект function a(v) { // v передается значением return { b: function () { console.log('b', v++) //4 return this }, c: function () { this.b() //5 return this }, d: function (w) { // w передается ссылкой console.log('d', w.v++) // 4 } } } a(v).b().c().d(w) console.log('-', v) // 4 console.log(w) // { v: 5 } наверное, стоит рассмотреть и такой пример ) |
Цитата:
просто это сама по себе ссылка на объект, потому внутри объекта можем что-то менять но сделав, например, w = null внутри метода, мы не поменяем внешнюю w. Потому что она была передана по значению |
Alexandroppolus, хорошее замечание )
|
Часовой пояс GMT +3, время: 17:58. |