2013-02-22 4 views
0

어떻게 호이스트가이 동작을 설명합니까?Javascript hoisting odd behavior

for(var i = 0; i < 4; i++) { 
    setTimeout(function() { 
     alert("i is: " + i); 
    }, i * 200); 
} 

이것의 출력은 4, 4, 4, 4

이것은 문헌에서 자주 권상 위험한 예로서 사용된다. i 변수가 함수 범위에 바인드되어 모든 호출간에 공유되므로 실행 시간에 따라 for 루프를 마쳤으므로 후자의 출력이 4 일 수 있습니다. 그러나 초기 호출은 0 * 200 또는 0의 시간 초과를 지정합니다. 따라서이 함수가 즉시 4 미만일 때 즉시 실행해야한다고 생각합니다.이 함수의 모든 출력이 4가되는 이유는 무엇입니까?

+4

호이 스팅과 아무 관련이 없기 때문이 아닙니다. 지연으로 '0'을 전달하더라도 브라우저에서 최소 지연은 약 10ms입니다. –

+0

나는 온라인으로 읽은 예제를 오해의 소지가 있다고 생각했다. 나는. http://thecomputersarewinning.com/post/a-dangerous-example-of-javascript-hoisting/ –

답변

1

호이 스팅과 아무 관련이 없기 때문이 아닙니다.

지연으로 0을 전달하더라도 브라우저에서 최소 지연은 약 10ms입니다. 어떤 지연 시간이 지나면 함수는 즉시 실행되지 않습니다. MDN documentation에서

:

그것은 기능이나 코드가 setTimeout()를 호출 한 쓰레드까지 실행할 수없는 경우에 종료 된 점에 유의하는 것이 중요합니다.

따라서 콜백이 호출되기 전에 for 루프가 이미 종료되었습니다.

관련 질문 : 그러나, 초기 호출이 0 * 200 또는 0의 타임 아웃을 지정하고 같은 나는이 실행해야한다고 생각

1

" 즉시 ... "

여러 스레드를 사용할 수있는 환경에서 발생할 수 있지만 단일 스레드 환경에서는 현재의 실행 흐름이 완료 될 때까지 자유롭게 계속됩니다.

즉, 첫 번째 setTimeout 콜백이 발생하기 전에 루프가 계속되고 완료됩니다.

루프가 10,000 밀리 초를 완료하는 경우에도 루프가 계속 진행되어 첫 번째 콜백이 시작됩니다.


이 데모를보십시오 : 첫 번째 setTimeout이 설정 한 후

var start = Date.now(); 

for(var i = 0; i < 4; i++) { 

    // set up the first timeout 
    setTimeout(function() { 
     alert("i is: " + i); 
    }, i * 200); 

    while (Date.now() - start < 1000) ; // block for 1000 ms 
} 

을, 우리가 1000MS에 대한 차단합니다. alert() 호출의 결과는 여전히 동일합니다. 이것은 동기식 흐름이 실행 예정인 비동기 코드와 관계없이 계속되기 때문입니다.

0

네 개의 은 첫 번째 타이머가 만료되고 익명 메서드 호출이 시작되기 전에 루프 내에서 setTimeout 호출을 호출합니다 (). 결과적으로 실행시 결과는 항상 4입니다. setTimeout 타이머 지연은 절대로 보장되지 않습니다.