자바스크립트도 다른 언어와 마찬가지로 스코프, 즉 유효 범위가 있으며 이 유효 범위 안에 변수와 함수가 존재한다.
자바스크립트에서는 for, if와 같은 구문은 유효 범위가 없고, 오직 함수만이 유효 범위의 한 단위가 된다.
이 유효 범위를 나타내는 스코프[[scope]]가 프로퍼티로 각 함수 실행 컨텍스트내에서 연결리스트 형식으로 관리되는데,
이를 스코프 체인이라고 한다.
1. 전역 실행 컨텍스트에서의 스코프 체인
var num1 = 1;
var num2 = 2;
console.log(num1); // 1
console.log(num2); // 2
전역 실행 컨텍스트에서는 자신이 최상위에 위치하는 변수 객체다.
따라서 이 변수 객체의 스코프체인은 자기 자신만을 가진다.
2. 함수를 호출한 경우 생성되는 스코프 체인
// 함수를 호출한 경우
var name = 'oppa';
function say() {
var name = 'coding';
console.log(name); // 'coding'
}
say();
console.log(name); // 'oppa'
전역 컨텍스트가 생성되고 say 함수 객체가 만들어진다.
함수 객체가 생성될 때, 그 함수 객체의 [[scope]]는 현재 실행되는 컨텍스트의 변수 객체에 있는 [[scope]]를 그대로 가져간다.
따라서 say 함수 객체의 [[scope]]는 전역 변수 객체가 된다.
say(); 로 함수를 실행하면 새로운 say 실행 컨텍스트가 만들어지는데, 이때 say() 함수의 실행 컨텍스트 스코프 체인은 호출한 함수 객체의 [[scope]] 프로퍼티를 그대로 복사한 후, 현재 생성된 객체를 복사한 스코프 체인의 맨 앞에 추가한다.
위 그림에서 name변수는 say활성 객체에서 먼저 탐색하고, 없으면 전역 객체를 탐색한다.
- 각 함수 객체는 [[scope]] 프로퍼티로 현재 컨텍스트의 스코프 체인을 참조한다.
- 한 함수가 실행되면 새로운 실행 컨텍스트가 생성되는데, 현재 실행되는 함수 객체의 [[scope]] 프로퍼티를 복사한후 새롭개 생성된 활성 객체를 해당 체인의 제일 앞에 추가한다.
3. 심화
var name = 'oppa';
function print(fn) {
var name = 'coding';
fn();
}
function say() {
console.log(name);
}
print(say); // 'oppa'
각 함수의 객체가 생성될 당시 실행 컨텍스트가 무엇인지를 생각해야한다.
print, say 함수 모두 각 함수 객체가 처음 생성될때 [[scope]]는 전역 객체의 [[scope]]를 참조한다.
따라서 각 함수가 실행될 때 실행 컨텍스트의 스코프 체인은 전역 객체와 그 앞에 새롭게 만들어진 활성 객체가 추가된다.
이렇게 만들어진 스코프 체인으로 식별자 인식이 이루어진다.
식별자 인식은 스코프 체인의 첫 번째 활성(변수) 객체부터 시작하여, 식별자와 대응되는 이름을 가진 프로퍼티가 있는지를 확인한다.
첫 번째 객체에서 대응되는 프로퍼티를 발견하지 못한다면, 다음 객체로 이동하는 식으로 찾을 때가지 계속된다.(= 스코프 체이닝)
by 소년코딩
추천은 글쓴이에게 큰 도움이 됩니다.
악플보다 무서운 무플, 댓글은 블로그 운영에 큰 힘이됩니다.