본문 바로가기

Programming/Javascript

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

 

스코프 체인

앞서 살펴본 실행 컨텍스트의 변수 객체 생성 과정을 기억하신다면, 변수 객체의 요소 중 하나였던 [[scope]]를 기억하실 것입니다. 우선 스코프 체인은 Javascript에서 선언된 변수들을 사용 범위(유효 범위)를 나타내는 단위이자 흐름입니다. 즉, 함수와 중괄호( { } ) 블록 내에서 사용된 변수가 어디에서 선언되었는지, 어디서 선언된 변수인지를 확인하기 위한 구조를 의미하게 됩니다. 우리가 배웠던 프로토타입 체이닝과 비슷한 개념이죠.

 

Javascript가 일반적인 OOP 프로그래밍 언어와 다른 부분은 여기에 있습니다. 통상적으로 C나 JAVA 등의 언어에서 변수의 사용 범위는, 해당 변수가 선언된 블록에 한정됩니다. 즉, 어떤 중괄호 블록에서 선언된 변수는 해당 블록이 끝나는 순간 사라지게 됩니다. 하지만 Javascript의 유효 범위의 기준은 함수 그 자체입니다. 변수 객체의 [[scope]]에 정의된 [List] 타입의 스코프 체인에 따라 변수의 사용 범위가 정해지게 됩니다. 

 

아마 현재 단계에는 이 설명이 와닿지 않을 것입니다. 하나씩 살펴보도록 하겠습니다. 

 

 

 

전역 실행 컨텍스트

아래와 같이 간단한 코드가 있다고 가정해 봅시다. 그리고 이 상황에서 형성되는 실행 컨텍스트를 함께 살펴보겠습니다.

 

var testA = 125;
var testB = 999;

console.log(testA);
console.log(testB);

 

우선 소스 파일에 위의 코드만 작성되었다고 가정하면, 별도의 함수는 선언되거나 실행되지 않고 두 개의 변수 testA 그리고 testB만 선언된 상태입니다. 그리고 두 개의 변수를 출력하는 코드만 작성되어 있습니다. 이 상태에서 코드가 실행된다면, 단 하나의 실행 컨텍스트와 변수 객체만 만들어지게 됩니다. 이 상태에서 만들어지는 그 하나의 실행 컨텍스트는 자체가 최상위 컨텍스트인 '전역 컨텍스트'가 됩니다. 

 

그리고 여기서 생성되는 [[scope]]에는 변수 객체 자기 자신만이 들어가게 됩니다. 이때 이 변수 객체가 '전역 객체'로서 정의됩니다. 참조할 상위 컨텍스트가 없는 최상위의 변수 객체가 되는 것이죠. 이를 그림으로 표현해 보겠습니다.

 

 

여기서 다시 한번 짚고 넘어가면, [[scope]]에서 참조하는 '전역 객체'는 var1, var2가 포함된 변수 객체입니다. 즉 변수 객체 자기 자신이죠. 다만 이 코드 상에서는 스코프 체인이 발생할 일이 없기 때문에 용도가 크게 와닿지는 않을 것입니다. 그럼 이 전역 코드에 함수 하나를 새롭게 정의하고, 해당 함수를 실행해 보도록 하겠습니다.

 

var testA = 125;
var testB = 999;

function func() {
    var testA = 11;
    var testB = 22;
    console.log(testA);
    console.log(testB);
}

func();

console.log(testA);
console.log(testB);

 

이제 이 코드에서 어떤 일이 벌어지는지를 차근차근 살펴보겠습니다. 우선 func( )라는 함수가 실행되었으므로 새로운 func 실행 컨텍스트가 생성됩니다. 여기에는 func( ) 함수가 가진 변수들이 생성되겠죠? 변수명은 동일한 testA, testB 입니다. 그럼 여기서 주의해서 봐야 할 부분은 func 컨텍스트의 변수 객체가 갖게 되는 [[scope]] 입니다. 

 

우선, func( )는 전역 컨텍스트에서 선언된 함수이기 때문에 기본적으로 전역 컨텍스트의 변수 객체가 갖고있는 [[scope]]를 그대로 복사해 옵니다. 그리고, func 변수 객체를 그 위에 스택(stack) 형태로 쌓아 올립니다. 즉, 스코프 체인은 현재의 실행 컨텍스트의 변수 객체 + 상위 컨텍스트의 스코프 체인 형태로 생성됩니다.