2012-06-21 3 views
5

JavaScript 범위 규칙을 이해하려고합니다. 제가 교과서에서 읽었던 것과 문서가 혼란 스럽습니다.JavaScript 범위 및 실행 컨텍스트

JavaScript는 정적 (또는 어휘 적) 범위 언어입니다. 변수 이름을 변수 (정의)에 바인딩하려고하면 코드의 어휘 구조가 사용됩니다.

실행 컨텍스트는 호출 스택의 스택 프레임과 비슷합니다. 각 실행 컨텍스트에는 (연관된 함수의) 모든 로컬 변수가 정의되는 변수 객체가 있습니다. 이러한 변수 오브젝트는 스택의 맨 위에있는 변수 오브젝트에서 스택 맨 아래의 변수 오브젝트 (창 오브젝트)에 이르는 '범위 체인'을 제공하기 위해 함께 링크됩니다. 이 스코프 체인은 변수 이름을 변수에 바인딩 할 때 위에서 아래로 검색됩니다. 이것은 C/C++/Java와 같이 정적으로 범위가 지정된 언어와 매우 유사합니다.

C/C++/Java와 관련하여 다음과 같은 중요한 차이점이 하나 있습니다. 아래 예제와 같이 호출 스택에 스택 프레임이없는 함수에서 정의 된 변수에 액세스 할 수 있습니다.

var color = "red"; 
var printColor; 

function changeColor() { 
    var color = "green"; 

    printColor = function(msg) { 
     alert(msg + color); 
    } 
    printColor("in changeColor context, color = "); // "green" 
} 

changeColor(); 

// stack frame for "changeColor" no longer on stack 
// but we can access the value of the variable color defined in that function 

printColor("in global context, color = "); // "green" 

이 권리가 있습니까? 내가 알아야 할 다른 문제가 있습니까? 미리

덕분

+4

JavaScript에 대한 실행 컨텍스트 및 스택은 무엇입니까? (http://davidshariff.com/blog/what-is-the-execution-context-in- javascript /) –

+2

이것을 * 클로저 *라고합니다. 'printColor'에 할당 한 함수는 함수가 종료 된 후에도'changeColor'에 정의 된 모든 변수에 접근 할 수 있습니다. 나는 이것이 C.에 어떻게 있는지 모른다. –

+0

@FelixKling 거의. 그러나 changeColor는 전역 범위에서도 정의되므로 범위가 가비지 수집되지 않습니다. – webduvet

답변

2

이것은 실제로 C/C++ 및 자바 스크립트 간의 주요 차이점이다 자바 스크립트 객체가 엔진에 의해 회수 될 수 있음을 의미 참조 카운트, 가비지 컬렉션 언어 때 그들이 더 이상 그들에 대한 언급이 없습니다. printColor에 할당 한 함수는 스택 자체에 있지 않습니다. 즉, 은 C 또는 C++에 있기 때문입니다. 동적으로 할당 된 다음 현재 범위 외부의 변수 에 할당됩니다. changeColor에서 제어 되돌아가 익명 함수는 여전히 외부 printColor 보낸 1 참조 카운트를 갖는 경우 그래서, 의미하며, 따라서 상기 외부 범위에서 사용할 수있다.

그래서, 당신의 예는 범위 지정 문제를 너무 많이하지 않습니다 - 당신이 changeColor의 기능 범위의 외부 printColor 를 선언하는 것이 분명하다. changeColor을 정의하면 새로운 기능 범위에 closes의 상위 값 printColor이 액세스 가능하도록 정의됩니다. 당신이 printColor의 두 번째, 내부 정의에 var를 추가하는 경우처럼 전투가 말했다, 그것은 shadowprintColor거야 당신은 선언과 그 기능 블록 외부 액세스 할 수 없습니다.

알고 있어야 할 다른 문제는 상당수 있습니다. 원래 시작에 대한 내 게시물에 대한 내 댓글을 참조하십시오.

+0

아아아, 나는 질문을 잘못 읽었을 수도있다. 그러나 나는 내가 썼던 것이 아직도 물을 가지고 있다고 생각한다. –

+0

printColor가 스택에 없다고 말하면 printColor를 나타내는 객체라고 가정합니다. printColor가 호출되면 실행 컨텍스트/스택 프레임이 스택에 푸시됩니다. 아니면 내가 잘못 했니? – asterix

0

항상 어휘 스코핑은 함수가 호출 될 때가 아니라 정의 될 때 스코프 체인과 함께 실행됩니다.

익명 함수는 전역 범위 대신 changeColor 함수의 로컬 범위에 정의됩니다.따라서 다시 실행될 때, 로컬의 changeColor 영역에 열거 된 녹색을 인쇄합니다.