본문 바로가기

Language/Java Script

자바스크립트 스코프 체인

각각의 함수는 [[scope]프로퍼티로 자신이 생성된 실행 컨텍스트의 스코프 체인을 참조한다.

함수가 실행되는 순간 실행 컨텍스트가 만들어지고, 이 실행 컨텍스트는 실행된 함수의 [[scope]] 프로퍼티를 기반으로 새로운 스코프 체인을 만든다.

 

1. 전역 실행 컨텍스트의 스코프 체인

var var1 = 1;
var var2 = 2;
console.log(var1); // 출력결과 : 1
console.log(var2); // 출력결과 : 2

  · 스코프 체인 : 참조할 상위 컨텍스트가 없다. 전역 실행 컨텍스트, 전역 변수 객체로 생성된다.

 

2. 함수를 호출한 경우 생성되는 실행 컨텍스트의 스코프 체인

var var1 = 1;
var var2 = 2;

function func(){
	var var1 = 10;
    var var2 = 20;
    console.log(var1); //출력 결과 : 10
    console.log(var2); //출력 결과 : 20
}
func();
console.log(var1); //출력 결과 : 1
console.log(var2); //출력 결과 : 2

  · 각 함수 객체는 [[scope]] 프로퍼티로 현재 컨텍스트의 스코프 체인을 참조한다.

  · 실행된 함수의 실행 컨텍스트는 현재 실행되는 함수 객체의 [[scope]]프로퍼티를 복사하고,

    새롭게 생성된 변수 객체를 해당 체인의 제일 앞에 추가한다.

  ∴ 즉 스코프 체인 = 현재 실행 컨텍스트의 변수 객체 + 상위 컨텍스트의 스코프 체인

 

  ※ 스코프 체인 이해 확인 

var value = "value1";

function printFunc(){
	var value = "value2";
    
    function printValue(){
    	return value;
    }

	console.log(printValue());
}

printFunc(); //출력 결과 : value2

var value = "value1";

function printValue(){
	return value;
}
function printFunc(func){
	var value = "value2";
    console.log(func());
}
printFunc(printValue); // 출력결과 : value1

  1)스코프 체인으로 식별자 인식(Identifier resolution)이 이루어진다.

    · 식별자 인식은 스코프 체인의 첫번째 변수 객체부터 시작한다.

  2)식별자와 대응되는 이름을 가진 프로퍼티가 있는지를 확인한다.

    · 함수를 호출할 때 스코프 체인의 가장 앞에 있는 객체가 변수 객체이므로, 이 객체에 있는 공식 인자, 내부함수, 지역 변수에 대응되는지 먼저 확인한다. 첫번째 객체에서 찾지 못하면 다음 객체로 넘어간다. 

 

Note

1. with 를 통해 해당하는 객체의 실행 컨택스트를 콜스택에 추가한다.

var y = {x:5};

function withExamFunc(){
	var x = 10;
    var z;
    
    with(y){
    	z = function(){
        	console.log(x); // 출력 결과 : 5 (y 객체의 x가 출력)
        }
    }
    z();
}
withExamFunc();

2. 호이스팅

foo();
bar();

var foo = function(){
	console.log("foo and x = " + x);
};

function bar(){
	console.log("bar and x = " + x);
}

var x = 1;
var foo;

function bar(){
	console.log("bar and x = " + x);
}

var x;

foo(); // TypeError
bar();

foo = function(){
	console.log("foo and x = " + x);
};

x = 1;

함수 생성 과정에서 변수 foo, 객체 bar, 변수 x를 차례로 생성한다. foo와 x에는 undefined가 할당된다.

실행이 시작되면 foo(), bar()를 연속해서 호출하고 foo에 함수 객체의 참조가 할당되며, 변수 x에 1이 할당된다.

결국, foo()에서 "TypeError"에러가 발생한다. foo가 선언되어 있긴 하지만 함수가 아니기 때문이다.

foo()를 주석 처리한 후 실행하면 "var and x  = undefined"가 출력된다. x에 1이 할당되기 전에 실행했기 때문이다.