본문으로 바로가기

[Javascript] var, const와 let

category Language/Javascript 2020. 3. 12. 19:28

🔍 var, const와 let의 차이

간단하게 요점만 말하면,

var function-scoped이고, let, const block-scoped입니다.


1. var (function-scoped)

// var는 function-scope이기 때문에 for문이 끝난다음에 i를 호출하면 값이 출력이 잘 된다.
// 이건 var가 hoisting이 되었기 때문이다.
for(var j=0; j<10; j++) {
  console.log('j', j)
}
console.log('after loop j is ', j) // after loop j is 10


// 아래의 경우에는 에러가 발생한다.
function counter () {
  for(var i=0; i<10; i++) {
    console.log('i', i)
  }
}
counter()
console.log('after loop i is', i) // ReferenceError: i is not defined

그럼 항상 function을 만들어서 호출해야 할까? 그건 아니다.

javascript에서는 immediately-invoked function expression (or IIFE, pronounced "iffy")라는것이 있다.

IIFE로 function-scope인거 처럼 만들 수가 있다.

하지만 IIFE는 function-scope처럼 보이게 만들어주지만 결과가 같지는 않다.

또한 코드 중간에 의도치않은 hoisting을 막기 위해서 use strict도 사용해야한다.

한마디로 넘 복잡하다.

2. let, const(block-scoped)

  • es2015에서는 let, const가 추가 되었다.

javascipt에는 그동안 var만 존재했기 때문에 아래와 같은 문제가 있었다.

// 이미 만들어진 변수이름으로 재선언했는데 아무런 문제가 발생하지 않는다.
var a = 'test' 
var a = 'test2' 

// hoisting으로 인해 ReferenceError에러가 안난다.
c = 'test' 
var c

하지만 let, const를 사용하면 var를 사용할때 생기는 문제점들을 보완할 수 있다.

 

let과 const의 공통점은 var와 다르게 변수 재선언 불가능이다.

let과 const의 차이점은 변수의 immutable여부이다.

 

let은 변수에 재할당이 가능하지만,

const는 변수 재선언, 재할당 모두 불가능하다.

// let
let a = 'test'
let a = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
a = 'test3'     // 가능

// const
const b = 'test'
const b = 'test2' // Uncaught SyntaxError: Identifier 'a' has already been declared
b = 'test3'    // Uncaught TypeError:Assignment to constant variable.

let, const가 hoisting이 발생하지 않는건 아니다.

var가 function-scoped로 hoisting이 되었다면

let, const는 block-scoped단위로 hoisting이 일어나는데

c = 'test' // ReferenceError: c is not defined let c
let c

위에 코드에서 ReferenceError가 발생한 이유는 tdz(temporal dead zone)때문이다.

let은 값을 할당하기전에 변수가 선언 되어있어야 하는데 그렇지 않기 때문에 에러가 난다.

이건 const도 마찬가지인데 좀 더 엄격하다.

// let은 선언하고 나중에 값을 할당이 가능하지만
let dd
dd = 'test'

// const 선언과 동시에 값을 할당 해야한다.
const aa // Missing initializer in const declaration

이렇게 javascript에 tdz가 필요한 이유는 동적언어이다 보니깐 runtime type check 가 필요해서이다.


참고: https://gist.github.com/LeoHeo/7c2a2a6dbcf80becaaa1e61e90091e5d