ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 렉시컬 스코프(정적 스코프)
    JavaScript 2023. 6. 15. 21:13

     

    클로저에 대해서 공부를 하는데 렉시컬 스코프에 대한 얘기가 반복적으로 나와 한번 정리해 보려 합니다. 

     

    한 번쯤 생각해 보신 적 있을 거예요.

    자바스크립트 엔진이 우리가 짠  자바스크립트 소스코드를 어떻게 인식하고 처리해서 우리가 원하는 결과를 도출해 줄까?

     

    자바스크립트 엔진은 소스코드를 2개의 과정, 즉 "소스코드의 평가"와 "소스코드의 실행" 과정으로 나누어 처리해요.

    저는 처음에 "소스코드의 평가"과정을 생각하지 못했어요. 단순하게 그냥 코드는 실행된다고만 생각했죠.

    하지만 아니에요. 실행을 위해서는 미리 실행을 위한 정보를 수집하는 과정이 필요하답니다. 이 단계가 "소스코드의 평가" 과정입니다. 

     

    "소스코드의 평가" 과정에서는 실행 콘텍스트를 생성하고 변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 만들어 실행 컨텍스트가 관리하는 스코프에 등록합니다.

    이러이러한 정보들이 코드를 실행하면 필요할 것이니 참조하기 좋게 실행 컨텍스트가 관리하는 것에요. 

     

    "소스코드의 평가" 과정이 끝나면 평가과정에서 정리했던 선언문을 제외한 나머지 소스코드가 순차적으로 실행되기 시작합니다! 즉, 런타임이 시작되는 거죠! 이때 소스코드 실행에 필요한 정보, 즉 '소스코드의 평가 ' 과정에서 정리했던 정보를 실행 컨텍스트가 관리하는 스코프에서 검색해서 알려주게 됩니다. 

     

    이렇게 실행 후 변수 값의 변경 등 소스코드의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록하게 됩니다. 

     

    예를 들어보죠!

     

    var x;
    x = 1;

     

    먼저 자바스크립트 엔진은 "소스코드의 평가" 단계를 실행하겠죠?

    선언문인 var x 만 실행 컨텍스트가 관리하는 스코프에 저장돼요.

     

    x undefined

     

    다음은 "소스코드의 실행" 과정이 시작돼요. 

    선언문 코드는 앞에서 이미 처리했으므로 x = 1 코드만 실행됩니다. 이때 x가 실행 컨텍스트에 있는지 확인해서 있으면 값을 할당해 줍니다. 

     

     x 1

     

    이쯤 되니 실행 컨텍스트가 꽤 중요한 역할을 하고 있다는 것을 알 수 있겠죠?

    그래서 한번 더 정리해 봅시다!

     

    실행 컨텍스트는 소스코드를 실행하는 데 필요한 환경(정보)을 제공하고 코드의 실행 결과를 실제로 관리하는 영역입니다. 

     

    좀 더 구체적으로, 실행 컨텍스트는 1) 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와  2) 코드 실행 순서 관리를 구현하는 내부 메커니즘(실행 컨텍스트의 스택으로 관리됩니다.)으로 , 모든 코드는 실행 컨텍스트를 통해 실행되고 관리됩니다!

     

    그래서 왜 글 제목이 렉시컬 환경인데 실행 컨텍스트 얘기만 줄줄이 하냐? 고 물으시면 이제 나옵니다... (저도 이 내용이 이렇게 길 줄 몰랐어요.)

     

    실행 컨텍스트에 들어있는 식별자에 대한 정보 그리고 식별자가 들어있는 스코프를  실행 컨텍스트의 렉시컬 환경이라고 해요.

     

    하위의 렉시컬 환경이 상위의 렉시컬 환경과 연결되어(스코프 체인) 외부 환경의 정보를 참조하는 일이 빈번히 일어나는 것을 알고 있을 거예요!

     

    이렇게 상위 렉시컬 환경(상위 스코프)의 정보를 참조하기 위해서는 상위 스코프를 결정해야 해요!

     

    💡 자바스크립트는 렉시컬 스코프를 따르므로 함수를 어디서 호출했는지(동적 스코프)가 아니라 함수를 어디서 정의했는지에 따라 상위 스코프를 결정합니다. 

     

    이처럼 참조해야 하는 상황에서 상위 스코프 결정은 함수가 정의된 환경(위치)에 의해 결정됩니다. 이것이 렉시컬 스코프(정적 스코프)입니다. 

     

    즉, 함수를 정의한 위치 = 함수의 상위 스코프

     

     

    예제를 통해 볼게요!

     

    var x = 1;
    
    function foo() {
    	var x = 10;
        bar();
    }
    
    function bar() {
    	console.log(x);
    }
    
    foo(); //?
    bar(); //?

     

    위 예제의 실행결과는 bar 함수의 상위 스코프가 무엇인지에 따라 결정되겠죠?

     

    bar 함수는 전역에서 정의된 전역함수이므로 상위 스코프는 전역입니다!

    그래서 x의 값으로 상위 스코프의 x = 1 값을 참조받아 foo()와 bar()의 결과는 1이 됩니다.

     

     

     

     

     

     

     

     

     

    반응형

    댓글

Designed by Tistory.