var, let, const 비교

Hyunsoo Han·2019년 12월 28일
2

Javascript

목록 보기
1/2

var, let, const

Scope level

var는 function-level scope (함수 레벨 스코프)이고, letconst는 block-level scope (블록 레벨 스코프) 이다.

Scope

Scope (스코프)는 참조 대상 식별자 (identifier, 변수, 함수명과 같이 다른 대상과 구분해낼 수 있는 유일한 이름)를 찾아내기 위한 규칙이다.

var i = 0;
{ 
	i = 1;
    console.log(i); // 1
}
console.log(i); // 1

let j = 0;
{
	j = 1;
    console.log(j); // 1
}
console.log(j); // 0

함수 레벨 스코프는 함수 코드 블록 내에서 선언된 변수는 함수 내에서만 유효하고, 외부에선 유효하지 않다. 다만, 블록 내에서 전역 변수에 값을 할당할 시, 블록 외부에서도 그 할당된 값이 표시된다. 이와 다르게, 블록 레벨 스코프는 블록 코드 내에서 선언된 변수는 블록 내에서만 유효하며, 블록 내에서 전역 변수에 값을 할당할 시, 블록 외부에서는 할당된 값이 유효하지 않다.


중복 변수 선언

또, 같은 이름의 변수 선언을 var는 혀용하지만 let, const는 허용하지 않는다.

var foo = 123;
var foo = 456;	// 중복 선언 허용

let bar = 123;
let bar = 456;	// Uncaught SyntaxError: Identifier 'bar' has already been declared

호이스팅 (Hoisting)

자바스크립트는 모든 선언(var, let, const, function, function*, class)을 호이스팅한다.

Hoisting

Hoisting(호이스팅)은 var, let, const, 함수 선언문을 가장 먼저 파악하고, 이후 처리를 하는 것을 의미한다. 해당 스코프의 가장 상단에 위치한 것처럼 작동한다.

그러나, letvar와 달리, 변수 선언 이전에 해당 변수를 참조하게 되면, 참조 에러(Reference Error)가 발생한다. (var는 undefined 값을 갖는다.) 이는 let 키워드로 선언된 변수는 스코프의 시작에서부터 변수의 선언까지 일시적 사각지대 (Temporal Dead Zone; TDZ)에 빠지기 때문이다.

변수는 3단계에 걸처 생성된다.

1. 선언 단계 (Declaration phase)
   : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 이 변수 객체는 스코프가 참조하는 대상이 된다.
2. 초기화 단계 (Initialization phase)
   : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 초기화된다.
3. 할당 단계 (Assignment phase)
   : undefined로 초기화된 변수에 실제 값을 할당한다.

var의 경우, 선언 단계와 초기화 단계가 동시에 이루어진다. 즉, 스코프에 변수를 등록함과 동시에 undefined로 초기화한다. 따라서, 변수 선언문 이전에 변수를 참조할 경우, 스코프에 변수가 존재하기 때문에 에러가 발생하지 않고, undefined를 반환한다. 이후, 할당문에 도달하면 값을 할당받는다. 이를 변수 호이스팅이라 한다.

let의 경우, 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 스코프에 변수를 등록하지만, 변수 선언문에 도달해야만 초기화 단계에 들어간다. 초기화 이전에 변수를 참조하면 변수를 위한 공간이 메모리에서 아직 확보가 되지 않았기 때문에 참조 에러가 발생한다. 따라서, 변수 선언문에 도달하기 전까지 변수를 참조할 수 없다. 스코프의 시작 ~ 변수 선언문까지 구간을 일시적 사각지대인 Temporal Dead Zone; TDZ라 부른다.

참조

profile
이야 진짜 모르겠다

0개의 댓글