자바스크립트 스코프 호이스팅
1. 스코프(scope)
스코프란 변수들이 유효한 범위를 말한다(어디서 접근 할 수 있고 어디까지 영향을 미치는 지를 결정하는 것). 자바스크립트에서는 전역 스코프와 지역 스코프가 있다.
1-1. 전역 스코프
함수 외부에서 선언 되는 경우로 어디에서든 접근이 가능하다.
1-2. 지역 스코프
지역스코프는 함수 스코프와 블록 스코프로 구분할 수 있다.
함수 스코프는 함수 내 어디에서든 접근이 가능하며 함수 외부에서는 접근이 불가능하다. 블록 스코프는 이보다 좀 더 작은 범위로 if, for 등에서 {} 로 구분되는 부분이다.
function sayHello () {
let hello = 'Hello!'
console.log(hello)
if(true){
let bye = 'Bye!';
}
console.log(hello); //Error
}
sayHello() // 'Hello!' 출력 후 Error
console.log(hello) // Error, hello is not defined
위 예제에서 hello는 함수 스코프, bye는 블록 스코프가 적용된 것이다.
2. 호이스팅(hoisting)
호이스팅이란 선언문을 유효범위의 최상단으로 끌어올리는 것이다. 과거에는 let, const 가 아닌 var로 선언할 때 주로 많이 혼동을 일으켰다.
var temp = 'this is temp';
for(var temp=0; temp<5; temp++){
// do something
}
console.log(temp); // 5
과거 전통적 언어(C, java 등)에서 넘어온 사람들은 다음 코드를 보고 'this is temp'가 출력될 것으로 기대하지만 그렇지 않다. var의 경우에는 블록 스코프가 아니라 함수 스코프가 적용되기 때문에 for 에서 temp가 덮어씌워지기 때문이다.
위의 예제 코드를 var로 선언한 경우
function sayHello () {
var hello = 'Hello!'
console.log(hello)
if(true){
var bye = 'Bye!';
}
console.log(bye);
}
sayHello()
console.log(hello) // Error, hello is not defined
let으로 선언했을 때와 다르게 if 밖에서 bye를 불렀음에도 불구하고 에러가 발생하지 않고 정상출력이 된다. bye가 호이스팅이 된 경우이다.
호이스팅 된 코드로 예제를 재구성해보면
function sayHello () {
var hello;
var bye;
hello = 'Hello!'
console.log(hello)
if(true){
bye = 'Bye!';
}
console.log(bye);
}
sayHello()
console.log(hello) // Error, hello is not defined
와 같이 이해할 수 있다.
기존에는 이런 문제를 해결하기 위해 클로저 등을 사용해야 했지만, ES6부터 let, const 키워드의 등장으로 스코프를 쉽게 관리할 수 있다.
참고