2011-02-12 2 views
2

흥미로운 범위 체인의 사례는 많은 문서에서 설명하지 못했지만 이해하기 어렵습니다. 누군가 아래에 잘 주석 된 코드를 읽고 변수가 해결되는 방법을 설명하는 데 시간이 걸릴 수 있다면 매우 좋을 것입니다.마우스 처리기 내의 Javascript 실행 컨텍스트, 카운터 직관적 인 범위 체인

문서에 두 개의 직사각형 (DIV)이 있습니다. 등록 된 mousedown 리스너 내에서 mousedown에 대한 이벤트 리스너를 등록합니다. 이상한 일이 mouseup의 청취자 내에서 일어나고 있습니다.

두 실행 컨텍스트가 인수 다른 값 회 testfunc 호출에 의해 생성되어 상기 제 사각형의 mouseup에 listener 내

window.onload = function() { 
    test_func("horizontal"); // First Execution context 
    test_func("vertical"); // Second Execution Context 
} 

(가로)이 제 2 실행 환경 (세로)의 대향되는 사용되고 직관적 인 :

function test_func(dir) { 
    var X = 9; // variable which helps to track the execution contexts 
    if(dir === "horizontal") 
     X = 1; // leave at 9 if vertical 

    mouseup_vert = function() {} 
    mouseup_horiz = function() { 
     // Here the value of X I am getting is 9 whereas I am expecting 11 
     // QUESTION: Why I am getting the second execution context?? 
    } 
    mousedown_vert = function() { 
     // As expected the value of X here is 9 
     X=99; 
     // set X to 99 to check if during mouseup same exec context is picked 
     document.addEventListener("mouseup", mouseup_vert, false); 
    } 
    mousedown_horiz = function() { 
     // As expected value of X is 1, so using first execution context 
     X=11; 
     // set this to check if during mouseup I get a value of 11 
     document.addEventListener("mouseup", mouseup_horiz, false); 
    } 

    if (dir === "horizontal") { 
     e = document.getElementById("horiz");   
     e.addEventListener("mousedown", mousedown_horiz, false); 
    } else { 
     e = document.getElementById("vert");    
     e.addEventListener("mousedown", mousedown_vert, false); 
    }    
} 

답변

6

기능을 참조하여 변수 var으로 선언되지 않은 때문이다, 그래서 그들은 세계입니다.

둘째 호출로 덮어 쓰여지고 있습니다. X과 닫히고 값은 9입니다.


편집 :여기 효과적으로 무슨 일이 일어나고 있습니다. 간단히하기 위해 모든 변수를 동일한 범위로 만듭니다.

// "a" is referencing a function. 
var a = function() { alert('a'); }; 

    // "b" is referencing the same function that "a" is referencing. 
var b = a; 

    // The reference "a" holds to the function is being overwritten with a 
    //  reference to a new function. 
a = function() { alert("I'm a new function"); }; 

    // "c" is referencing the same function that "a" is referencing (the new one). 
var c = a; 

    // So what is "b" referencing? It is still the original function, because it 
    // picked up that reference *before* the original reference "a" held was 
    // overwritten. 

b(); // alerts 'a' 

... 또는 코드를 좀 더 특정 코드를 만들기 위해 : 정확히

// reference a function 
var mouseup_vert = function() { alert("I'm a mouseup function."); }; 


    // reference a function 
var mousedown_vert = function() { 
        // When this function is invoked, add a listener using 
        // whatever function is referenced by mouseup_vert 
       document.addEventListener("mouseup", mouseup_vert, false); 
}; 


    // The function currently referenced by "mousedown_vert" is passed here 
    // as the event handler. 
document.addEventListener("mousedown", mousedown_vert, false); 


    // Overwrite "mouseup_vert" just for kicks. 
mouseup_vert = function() { alert("I'm a completely different function."); }; 


    // NOW trigger a "mousedown" event. What happens? The function passed as the 
    // handler is invoked. 

    // What does that function do? It adds a "mouseup" handler. 

    // Which variable is referenced? "mouseup_vert". 

    // What is the current value of "mouseup_vert"? The new function, since we 
    // overwrote the reference to the original. 
+0

. "mouseup_foo"변수는 모두 전역 변수입니다. 그들은'var' 키워드로 선언되어야합니다 !! 또한 이벤트 핸들러 내부에서 이벤트 핸들러를 설정하는 것이 큰 문제가 될 것입니다. – Pointy

+0

@Pointy : 핸들러 할당에 대한 좋은 지적. – user113716

+0

세계적인 경우 X는 mousedown_horiz에서 11로 설정됩니다.이 값은 mouseup_horiz에서 볼 수있는 값이며, 이는 내가보고있는 것이 아니며 따라서 내 질문이 아닙니다. – Raks