2017-01-06 6 views
0

О выполнении функций непосредственно в JavaScript закрытия

var funcs=[]; 
 
for(var i=0;i<3;i++){ 
 

 
    funcs[i]=function(){ 
 
    console.log(i); 
 
    }; 
 
    } 
 
for(var j=0;j<3;j++){ 
 
    funcs[j](); 
 
    }

Таким образом, я знаю, что это будет оповещать 3 all.Because функции были названы после того, как я был назначен 3.

Но в ниже кода, я не могу понять, почему это происходит.

for(var i = 0; i < 10; i++) { 
 
    setTimeout(function() { 
 
     console.log(i); 
 
    }, 2000); 
 
}

на мой взгляд, когда я был назначен на 0, первая функция SetTimeout будет выполняться до того я был назначен 1.

Я прав в порядке этого цикл?

+0

Возможный дубликат [JavaScript закрытия внутри петли - простой практический пример] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical- пример) – cartant

+0

Вы получаете 3x3 по той же причине. * «первая функция setTimeout будет выполнена до того, как мне будет присвоено значение 1.» * Нет, все функции выполняются после того, как цикл завершен, и в какой точке 'i' имеет значение' 3'. Цикл не ждет таймаута. И это на самом деле очевидно из того факта, что вы получаете результат всех трех функций в * один раз * 2 секунды в будущем. Между каждым выходом не существует 2-секундной задержки. –

+0

Что значит «3x3»? И почему «все функции выполняются после завершения цикла»? – zyMacro

ответ

1

console.log (я) будет называться после того, как в течение цикла закончена, для контура, который из-за способа var является функцией области видимости. Будет 10 к тому времени (2000 мс), он достигнет инструкции console.log. Одним из способов дать ожидаемый результат является использование let вместо var. Однако вы удаляете некоторую поддержку браузера с помощью let.

Хорошее чтение по этой теме будет getify's "You Don't Know Js" book.

for(let i = 0; i < 10; i++) { 
 
    setTimeout(function() { 
 
     console.log(i); 
 
    }, 2000); 
 
}

+0

Мой вопрос в том, почему «console.log (i) будет вызван после завершения цикла for»? – zyMacro

+0

Петля для петли немедленно завершается. console.log находится внутри 'setTimeout', который будет ждать перед выполнением. Это происходит асинхронно по сравнению с циклом for. 'setTimeout' только мешает тому, что внутри него исполняется, до таймера. Все, что находится вне его, будет продолжать работать как обычно. – devilfart

+0

вы имеете в виду, что это «асинхронно», а не setTimeout, ожидая завершения цикла? – zyMacro

0

Вам нужно поместить переменную i в замыкание, иначе она будет переписана в каждой итерации цикла. То же самое происходит и для функции setTimeout, вы должны также ввести переменную i в закрытие.

var funcs=[]; 
 
for(var i=0;i<3;i++){ 
 

 
(function(i){ 
 
    funcs[i]=function(){ 
 
     console.log(i); 
 
    }; 
 
    })(i); 
 
} 
 

 
for(var j=0;j<3;j++){ 
 
    funcs[j](); 
 
    }

 Смежные вопросы

  • Нет связанных вопросов^_^