for(var i=1;i<5;i++){
setTimeout(function(){console.log(i)},i*1000);
}
여기서 for 루프가 먼저 완료되고
다음에 i 값이 5가 되었습니다
그러면 for 루프가 먼저 실행되는데 왜 i*1000이 실행되는 걸까요?
滿天的星座2017-05-18 11:02:35
for 루프가 실행되면 페이지에 4개의 타이머 함수를 작성하는 것과 같습니다. 이때 타이머 함수는 아직 실행되지 않았으며 타이머 시간이 되면 전역의 i 변수 값은 5입니다. 가 작동되면 타이머 기능이 순서대로 실행됩니다. 4 5를 순서대로 인쇄합니다.
이 예제는 클로저가 아닙니다. 클로저는 이렇게 작성해야 합니다. 이는 페이지에 즉시 실행되는 4개의 함수를 작성하는 것과 같습니다. 이 4개의 함수가 받는 실제 매개변수는 1, 2, 3, 4입니다. 클로저 특징에 따르면 타이머가 종료되면 타이머 함수는 외부 함수에서 수신한 실제 매개변수에 액세스할 수 있으므로 1, 2, 3, 4를 순서대로 인쇄합니다
으아아아给我你的怀抱2017-05-18 11:02:35
컴퓨터에서 모든 변수는 메모리에 저장할 공간을 열어야 하며, 그러면 모두 주소가 있습니다. C언어나 어셈블리 언어를 공부하신 분들이라면 더 잘 아실 겁니다.
먼저 내가 왜 매번 5를 출력하는지부터 이야기해보자. 왜냐하면 i의 공간(즉, i를 저장하는 데 사용되는 메모리 공간, 과학적으로 "스택"이라고 함)이 5번 수정되었고, 익명 함수가 실행되면 i의 공간은 5를 저장하기 때문입니다.
두 번째 매개변수가 매번 달라지는 이유를 설명해 보겠습니다. i*1000
并没有修改i
的值,而是会产生一个结果。那么这个结果必然要找地方去存。存储在哪呢?setTimeout
每被调用一次,都会开辟一段内存空间,其中一部分空间就用于存储它的两个参数。其中一个参数就是刚才i*1000
产生的结果。而setTimeout
被调用了5次,于是存储了5个结果!没错,是在5个不同的空间存储了5个结果,而不是像i
같은 공간이 5번 수정되었습니다! 상상할 수 있듯이 이 접근 방식은 메모리 집약적입니다.
이 설명이 이해가 되시나요?
phpcn_u15822017-05-18 11:02:35
for 함수가 메인 스레드에 들어가면 각 setTimeout이 차례로 작업 큐의 대기 큐에 들어갑니다. for가 실행된 후 작업 큐의 setTimeout이 메인 스레드에 들어가 실행됩니다. 클로저가 없으면 setTimeout이 클로저와 함께 실행될 때 i는 이미 5입니다. setTimeout이 작업 대기열에 들어갈 때 i 값이 저장됩니다.
자세한 내용은 이벤트 루프