본문 바로가기

Programming/Javascript

11. Javascript 실행 컨텍스트(4) - 스코프 체인 3

javascript logo image

 

앞서 살펴본 예제 코드의 구성과 거의 동일하지만, 약간의 선언 구조만 다른 예제를 통해 스코프 체인의 중요한 성질 하나를 더 살펴보도록 하겠습니다. 우선, 결론만 요약하여 설명하면 아래와 같습니다. 

 

* 실행 컨텍스트는 함수의 실행 시점에 생성된다.
* 단, 변수 객체의 스코프 체인은 해당 함수 객체의 생성(선언) 시점에 따라 형성된다.

 

문장만 봐서는 무슨 의미인지 선뜻 감이 오지 않으실 겁니다. 이제 앞에서 살펴본 예제와 새로운 예제를 비교해 실행해 보겠습니다. 아래 코드는 바로 직전 아티클에서 실행 컨텍스트와 변수 객체의 구조를 알아보기 위해 작성했던 코드입니다. 여기서 함수 printValue( )는 printFunc( ) 함수의 내부 함수로서 선언되어 있는 구조입니다. 

 

var value = "value1";

function printFunc() {
    var value = "value2";

    function printValue(){
        return value;
    }

    console.log(printValue());
}

printFunc();

 

 

 

그럼 이제, 다음 코드를 살펴보겠습니다. 여기서는 내부 함수 형태로 선언된 함수가 없고, 모두 전역 컨텍스트에 선언이 되어 있습니다. 그리고 printFunc는 특정 함수를 인자로 받아 해당 함수 안에서 실행하는 구조입니다. 어떤 함수 안에서 다른 함수를 실행한다는 것은 비슷하지만, 선언 구조가 조금 다릅니다. 그럼 이 예제의 실행 컨텍스트 구조를 도식화 해보겠습니다.

 

var value = "value1";

function printValue() {
    return value;
}

function printFunc(func) {
    var value = "value2";
    console.log(func());
}

printFunc(printValue);

 

 

우선 printValue( )와 printFunc( )라는 함수는 모두 전역 컨텍스트에서 선언되어있기 때문에, 전역 객체에서 확인할 수 있습니다. 그리고 여기서 printFunc( )가 실행되므로, printFunc 컨텍스트가 생성됩니다. 스코프 체인은 우선 상위 객체인 전역객체를 참조하고, 여기에 printFunc가 추가됩니다. 

 

여기서 printFunc 내부에서 특정 함수를 인자로 받아 실행하게 되는데, 인자로 사용되는 함수가 바로 전역 컨텍스트에 선언된 printValue입니다. printValue( )가 어쨌든 실행되었으므로 printValue컨텍스트가 형성됩니다. 그런데 이때, 스코프 체인에서 참조하는 변수 객체를 주의해야 합니다. 

 

위에서 설명했듯, 실행 컨텍스트는 함수의 '실행' 시에 생성되지만, 스코프 체인은 함수가 '선언'된 시점을 기준으로 형성됩니다. 실행은 printFunc 컨텍스트에서 이루어졌지만, printValue 선언은 전역 컨텍스트에서 이루어졌기 때문에, 스코프 체인 참조 영역은 전역 객체 + printValue 변수 객체로 이루어지게 됩니다. 그러므로 value라는 변수의 존재는 자기 자신에서 없을 경우 바로 전역 객체를 따라 검색하게 됩니다. 결국 여기서 출력하는 'value'는 전역 객체에 있는 value 즉 "value1"이 됩니다. 

 

실행 컨텍스트 생성과 참조 과정에 있어서 선언 시점, 그리고 실행 시점을 잘 구분해서 살펴봐야 합니다.