자바스크립트 var, let, const

김혜진·2019년 11월 29일
4

javascript

목록 보기
2/9

자바스크립트에서 사용되는 세 가지 변수들 var, let, const의 차이점이 무엇인지 간단하게 정리해보자.
먼저 그 차이점을 이해할 때에 있어서 가장 중요한 두 가지 키워드는 ScopeHoisting이다.

Scope와 Hoisting

Scope

- 유효 범위

변수가 선언되면 모든 코드에서 사용 가능한 것이 아니라 변수의 종류에 따라 사용 가능한 '유효 범위'가 정해지게 되는데 이를 Scope 스코프라 한다. 다시 말해, 스코프란 변수가 사용되는 유효 범위를 뜻한다. 종류는 크게 전역/ 지역 스코프로 나뉜다.

  • 전역 global: 어떤 함수나 블록에도 속하지 않은 최상단 스코프
  • 지역 local: 특정 함수나 블록 내부에 국한된 스코프
  • 함수 function
  • 블록 block
var global = 'global scope'; // 어떤 함수나 블록에도 속하지 않는다.

function foo() {
  var local = 'local scope'; // 함수 내에 존재한다.
}

* global과 local은 상대적 개념이 아니다.

- 접근 제한

스코프에서 또 하나 중요한 점은 내부 스코프에서 외부 스코프로 접근은 가능하지만, 그 반대의 접근은 불가하다는 것이다.

var global = 'global scope';

function foo() {
  var local = 'local scope';
  
  console.log(global); // 'global scope'
  console.log(local); // 'local scope'
}

foo();
console.log(global); // 'global scope'
console.log(local); // 외부에서 내부 스코프로 접근은 불가하다. Uncaught ReferenceError: local is not defined

 

Hoisting

- 최상단 선언

스코프 내에서 모든 변수 선언들을 위치에 관계없이 스코프의 가장 최상단으로 끌어올려 선언시키는 것을 뜻한다.

function first() {}
function secone() {}

var third = 'hello';
const fourth = 'world';

이러한 순서의 코드라도 사실 내부적으로는 변수 '선언'들이 호이스팅되어 아래와 같은 코드로 작동한다.

var third;
const fourth;

function first() {}
function secone() {}

third = 'hello';
fourth = 'world';

*변수 할당, 재할당은 해당되지 않고 선언만을 Hoisting 호이스팅한다.
*내부적인 처리이므로 실제로 코드가 변경되어 쓰여지는 것은 아니다.



var, let, const

var는 ES2015(ES6) 이전부터 사용되었고, letconst는 ES6에서 등장했다. 이 세 가지는 scopehoisting을 중점으로 뚜렷한 차이가 나타난다.

var

- 함수 스코프를 사용하며 재할당, 재선언 모두 가능하다.

var testVar = 1;
console.log(testVar); // 1

testVar = 2;
console.log(testVar); // 2

var testVar = '1';
console.log(testVar); // '1'

- undefiend로 초기화되어 호이스팅된다.

console.log(testVar); // undefiend
var testVar = 1;
console.log(testVar); // 1

 

Temporal Dead Zone (TDZ) ?

호이스팅시 undefiend로 값이 자동 초기화되는 var와 달리 let,const는 초기 값이 설정되지 않는다. 따라서 letconst의 경우 변수 값이 선언되고 난 후에야 실제 변수 사용이 가능하며 그 이전에는 ReferenceError를 발생시킨다. 이렇게 호이스팅 - 변수 선언 사이의 구간, 변수가 존재하기는 하나 선언되기 전까지의 구간을 Temporal Dead Zone이라 일컫는다.

- let과 const는 호이스팅 되지 않는 것인가?

에러가 발생하기는 해도 letconst 역시 변수의 존재를 알기에 에러가 발생하는 것이므로 호이스팅이 되고 있는 것이다. 나아가 에러를 발생시킴으로써 이후 발생 할 버그를 초기에 잡을 수 있다.

console.log(testLet); // Uncaught ReferenceError: Cannot access 'testLet' before initialization
let testLet = 'test tdz';
console.log(testLet); // 'test tdz'

console.log(testConst); // Uncaught ReferenceError: Cannot access 'testConst' before initialization
const testConst = 'test tdz';
console.log(testConst); // 'test tdz'

 

let

- 블록 스코프를 사용하며 재할당이 가능하고 재선언은 불가하다.

let testLet = 1;
console.log(testLet); // 1

testVar = 2;
console.log(testLet); // 2

let testVar = '1';
console.log(testLet); // Uncaught SyntaxError: Identifier 'testVar' has already been declared

- 호이스팅이 되긴 하나 변수 값 선언 전까지 TDZ 제한으로 ReferenceError를 발생시킨다

console.log(testLet); // Uncaught ReferenceError: Cannot access 'testLet' before initialization
let testLet = 1;
console.log(testLet); // 1

 

const

- 블록 스코프를 사용하며 재선언, 재할당 모두 불가하다.

const testConst = 1;
console.log(testConst); // 1

testVar = 2;
console.log(testConst); // Uncaught TypeError: Assignment to constant variable.

const testVar = '1';
console.log(testConst); // Identifier 'testVar' has already been declared

- let과 동일하게 호이스팅이 되긴 하나 변수 값 선언 전까지 TDZ 제한으로 ReferenceError를 발생시킨다

console.log(testConst); // Uncaught ReferenceError: Cannot access 'testConst' before initialization
const testConst = 1;
console.log(testConst); // 1

참고
what is the temporal dead zone

profile
꿈꿀 수 있는 개발자가 되고 싶습니다

0개의 댓글