[JavaScript] 변수 호이스팅

변수 선언

자바스크립트의 경우 변수를 선언할 때 var, let, const 키워드를 사용한다.
ES6 이전부터는 변수 선언을 오로지 var 키워드만을 이용했다고 한다.
그렇다면 변수 선언에 var 외에 let, const를 사용해야 하는 이유가 있을까?

블록 레벨 코스프 vs 함수 레벨 코스프

var키워드는 여러 단점을 가지고 있는데 그중 대표적으로 블록 레벨 스코프(block-level-scope)를지원하지 않고, 함수 레벨 스코프(function-level-scope)를 지원한다는 점!

함수 레벨 스코프의 경우 함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다.즉, 함수 내부에서 선언한 변수는 로컬 변수이고 외부에서 선언한 변수는 모두 전역 변수가 되는 것이다. 이로 인해 의도치 않게 전역 변수가 선언되어 부작용이 발생하기도 한다.

var a = "out of function"; // 함수 외부에 선언 (전역 변수)
function foo() {
    console.log(a); 
}
foo();

위와 같이 변수 a를 함수 밖에서 선언한 경우 전역변수로 처리되어 함수 내부에서 a를 참조할 수 있다.

function foo() {
  var b = "in of function"; // 함수 내부에 선언 (로컬 변수)
}
console.log(b);

그러나 변수를 함수 내부에서 사용하고 외부에서 참조하려고 했을 때는 아래와 같이 오류가 발생하는 것을 확인할 수 있다.

값의 재할당

위와 같은 단점들을 보완하기 위해 const, let 키워드가 생겨났다. 이 키워드들의 차이점 중 하나는 값을 재할당할 수 있는 지에 대한 여부이다.

var score = 80; // 변수 선언과 값의 할당
score = 90; // 값의 재할당

그렇다면 const 키워드로 값을 재할당해보면 어떨까.

const foo = 10;
foo = 100;


역시 예상대로 다음과 같이 오류가 발생함을 알 수 있다. const 키워드를 사용해 선언한 변수는 재할당이 금지된다. 따라서 const 키워드를 사용하면 상수를 표현할 수 있음! ( const, let 키워드에 대한 설명과 블록 레벨 코스트에 관한 내용은 추후에 따로 더 자세히 다뤄볼 예정 )

변수 선언 실행 시점과 호이스팅

console.log(score);
var score;

위와 같은 코드의 경우 변수를 참조하는 내용이 변수를 선언하는 내용보다 더 위에 있다. 이런 경우에 나로써는 당연히 에러가 출력될거라고 예상했는데 참조 에러가 발생하지 않고 undefined가 출력된다.
그 이유는 변수 선언이 소스코드가 순차적으로 실행되는 시점(런타임)이 아니라 그 이전 단계에서 미리 실행되기 때문이라고 한다.

즉, 자바스크립트 엔진이 소스코드를 실행하는 과정은 소스코드 평가 > 순차적 실행 순으로 진행된다.

이처럼, 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 한다.

📚 참고자료 : 모던 자바스크립트 Deep Dive

좋은 웹페이지 즐겨찾기