이 글에서는 Hoisting
과 변수의 유효범위
를 이해함으로써 자바스크립트가 어떻게 변수를 찾는지 알아볼 것이다.
변수의 유효범위란 어떤 변수가 유효한 범위를 의미함을 생각하면서 아래의 코드들을 보자.
먼저 c로 작성된 다음의 코드를 보자.
int main(){
if(true){
int number = 10;
}
printf(number);
}
이 코드는 블록안에있는 변수를 참조하니 당연히 작동되지 않는다.
하지만 아래의 javascript 코드는 정상적으로 작동한다.
function main(){
if(true){
var number = 10;
}
console.log(number);
}
main();
왜 이런 차이가 발생할까?
앞서 언급했듯 변수의 유효범위의 차이에 답이 있다.
C언어는 블록단위 유효범위를 사용한다. 즉 중괄호’{}’로 감싸져 있는것으로 변수의 유효범위가 달라진다는것이다.
하지만 javascript는 함수 유효범위
를 사용한다. 즉 블록이 기준이 아니라 함수로 구분한다는 것이다.
따라서 함수내부에서 중첩함수안에 있는 변수만 접근하지 못한다는 것이다.
Hoisting은 끌어올린다는 의미이다. 즉 변수를 끌어올린다는 것. 아까 예시를 조금 변형해보면..
function main(){
console.log(number);
if(true){
var number = 10;
}
}
main();
위 코드는 오류가 발생할 것 같지만 undefined
를 출력한다.
즉 변수 number
가 10으로 정의되기전에 이미 number
는 존재하던 것이다.
위 예시에서 확인할 수 있는것은 javascript가 변수의 선언을 함수의 상단 혹은 코드의 상단으로 hoisting한다는 것이다. 따라서 위의 코드는 다음과 같다.
function main(){
var number;
console.log(number);
if(true){
number = 10;
}
}
main();
hoisting이라는 특징을 코드에 반영하는 방법중 하나는 변수의 선언을 코드의 상단에 작성하는것이다.
이를 통해 프로그램의 동작을 명확히 할 수 있다.
변수의 값을 가져오고 수정하는등의 코드를 실행할때 어떻게 해당 변수를 찾는것 일까? 이 과정이 바로 변수해석(variable resolution)이다.
어떤 코드에 대해 변수유효범위를 나타내는 객체가 존재한다. 이 객체들은 자신의 프로퍼티로 해당 변수들(유효범위에 있는 변수들)을 가지고 있는다.
예를들어 전역객체는 전역변수들을 프로퍼티로 가지고 있으며, 함수의 지역변수나 매개변수를 프로퍼티로 가지는 객체도 존재한다.
위의 객체들을 포함한 리스트를 유효범위 체인
이라고 부르며,
변수해석과정은 이 리스트에서 원하는 변수를 찾는것 이다.
함수의 경우 함수가 정의될때 유효범위체인이 최초로 저장되는데 이때는 전역객체 및 상위 함수의 유효범위 체인이 저장된다. 이후 함수가 실행될때는 지역변수 및 매개변수에 대한 유효범위 객체가 추가되어 저장된다.
이를 응용하여 3가지 경우에 대해 유효범위 체인이 어떻게 생성되는지 생각해 볼 수 있다.
javascript에서는…