var, let, const 특징 및 호이스팅

Jeongkuk Seo
sjk5766
Published in
4 min readSep 13, 2018

오늘 개발 중에 갑자기 에러가 발생한다. 코드를 본다. 음..? 왜..? 코드를 간단히 추려 정리하면 아래 코드와 같다.

이 코드에서 발생한 에러를 통해 변수 선언 시 사용하는 keyword var, let, const의 차이점을 알게 되었고 여기에 정리한다.

호이스팅 (hoisting)

자바스크립트는 실행시점에 변수와 함수에 대해 호이스팅을 수행합니다. 호이스팅이란 사전적인 의미로 끌어올린다 라는 의미로 변수와, 함수를 소스의 맨 위의 위치로 이동합니다.

console.log(name) // undefined
var name = ‘seo’

위의 코드를 보면 첫 줄에 name을 출력하는데 에러가 나지 않고 undefined가 나옵니다. 왜냐면 실행시점에 호이스팅에 의해 var 변수가 아래와 같이 최 상단에 선언됩니다.

var name; // 실행시점에 name 변수가 hoisting 되어 해당 위치로 이동
console.log(name)
name = ‘seo’

let과 const 는 호이스팅 되지 않는다?? No!!

위에서 var 키워드로 선언 된 변수는 호이스팅 되었습니다. 그럼 ES 6에서 추가 된 let과 const 는 어떻게 되는지 보겠습니다.

console.log(name) //ReferenceError: name is not defined
let name = 'seo'

let으로 변수를 선언하면 에러가 발생합니다. 여기서 오해할 수 있는게, let 키워드로 선언된 변수는 hoisting 되지 않는구나 라고 오해하시는데 아닙니다.

var 뿐만 아니라 let과 const 키워드로 선언된 변수들도 호이스팅 됩니다. 아래 예제를 보겠습니다.

var name = ‘seo’ // 전역변수{
console.log(name) // name is not defined
let name = ‘seo’ / 지역변수
}

최 상단에 name 변수를 선언했는데 왜 console.log는 에러를 출력할까요. 그 이유는 {} 블록 내부에 let으로 선언된 name 변수가 호이스팅 되었기 때문입니다. let name 변수가 호이스팅 되지 않았다면 console.log의 결과는 전역변수가 가리키는 seo가 출력되어야합니다.

여기서 한 가지 의문이 들 수 있습니다. 좋아, let 으로 선언된 변수도 호이스팅 된다고? 그러면 왜 출력결과가 undefined가 아니라 name is not defined 에러가 발생하지?

이를 이해하기 위해서 자바스크립트에서 변수가 어떻게 할당되고 var와 let이 어떤 차이가 있는지 알아야 합니다.

변수의 3단계 생성과정

변수는 아래와 같이 3단계의 과정을 통해 생성됩니다.

  1. 선언단계 : 변수를 실행컨텍스트의 변수객체에 등록한다.
  2. 초기화 단계 : 실행 컨텍스트에 등록 된 변수객체에 대한 메모리를 할당한다. 이 단계에서 변수는 undefined로 초기화 된다.
  3. 할당단계 : undefined로 초기화 된 변수에 값을 할당한다.

var 키워드로 변수를 만들 경우, 선언단계와 초기화 단계가 동시에 이뤄집니다. 아래 예제를 다시 보겠습니다.

console.log(name) // undefined
var name = ‘seo’

위 코드에서 var 로 선언된 변수는 hoisting 되어 선언과 초기화가 동시에 이뤄지기 때문에 undefined로 출력됩니다.

하지만 let 키워드는 선언단계와 초기화 단계가 분리되어 진행됩니다.

console.log(name) // ReferenceError: name is not defined
let name = ‘seo’

let 키워드로 선언된 변수는 hoisting 되어 선언단계가 이뤄지지만 초기화 단계는 실제 let이 사용된 코드에 도착했을 때 이뤄집니다. 초기화 단계 이전에 변수에 접근하려하면 reference 에러가 발생합니다.

const 변수

const 변수는 let과 매우 유사하지만 차이점은 const 로 선언되면 값이 상수화되어 변경이 불가능합니다. 또한 const 로 선언될 경우 선언과 동시에 초기화를 해야 합니다.

var name;
name = 'seo'
const age = 29; // 선언과 동시에 초기화 필요//const age; // const 변수를 선언만 할 경우 에러가 발생
//age = '29';

변수 Scope

let과 const 로 선언된 변수는 블록 레벨 스코프를 가집니다. 즉, {} 내부에 변수를 선언하면 해당 블록 내부에만 생명주기를 유지합니다. 반대로 var는 함수 레벨 스코프를 가지므로, 블록 내부에 선언되어도 외부에서 접근할 수 있습니다.

{
let name = ‘seo’
}
console.log(name) // ReferenceError: name is not defined{
var age = 29;
}
console.log(age) // 29 , var는 함수 레벨 스코프

--

--