와 변수 - var, let, const의 차이점 알기

7344 단어 ES6JavaScriptES6

ES6와 ES6 이전의 변수


var

var name = "Kim";
name = "Lee";

console.log(name)
// Lee

var를 사용해 변수를 선언하면 재할당이 가능하여 값이 바로 변경된다. var의 이런 동작은 하나의 파일을 여러 사람이 작성하는 협업 시에 특히 문제가 될 수 있다.

이를 보완하기 위해 ES6에 등장한 것이 constlet이다.

const

const로 변수를 한 번 정의하면 읽기만 가능하고 재할당이 불가하다.

const name = "Kim";
name = "Lee";

// Error: "name" is read-only

그러나 경우에 따라 변경이 되기도 하므로 완벽히 안전하지는 않음을 참고한다.

const person = {
  name: "Kim"
};

person.name = "Lee"; // const로 선언한 객체의 값을 변경한다. 

console.log(person)
// Object {name: "Lee"} - 값이 변경되었다. 

let

const와 함께 ES6에 도입된 letvar와 마찬가지로 재할당이 가능하다.

let name = "Kim";
name = "Lee";

console.log(name)
// Lee 

그렇다면 letvar의 차이는 무엇일까?

일시적 사각지대(TDZ, Temporal Dead Zone)


(1)
var myName = "Lee";
console.log(myName); 
// Lee

(2)
console.log(myName);
var myName = "Lee";
// undefined

(3)
console.log(myName);
// ReferenceError: myName is not defined

(1)은 정상적인 코드이다.

(2)에서는 변수에 값을 할당하기 전에 콘솔 출력이 먼저 일어난다. 자바스크립트는 원칙적으로는 코드를 위에서부터 차례대로 실행하므로, 변수에 값이 할당 되기 전에 변수를 출력하면 undefined인 것이 그럴듯해 보인다.

그런데 (3)을 보면, (2)처럼 변수에 값이 할당 되지 않은 상태에서 콘솔 출력이 일어나는데 undefined가 아닌 레퍼런스 에러가 나온다. 정의된 적이 없다는 뜻이다.

생각해보면 자바스크립트는 위에서부터 차례대로 코드를 실행하니 (2)에서도 레퍼런스 에러가 발생하는 것이 합당한데 왜 undefined를 출력하는 것일까? 이는 호이스팅(hoisting) 때문이다.

호이스팅(Hoisting)

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

호이스팅은 코드 실행 이전에 변수 및 함수 선언을 스코프 맨 위로 끌어올려두는 자바스크립트의 매커니즘이다.

호이스팅의 원리에 따라 위 (2)의 코드는 실제로 이렇게 동작했다.

var myName;
console.log(myName);
myName = "Lee";
// undefined

var로 선언한 변수가 우선 맨 위로 끌어 올려진다. 그리고 두번째 줄에서는 아직 값이 할당되지 않았으므로, 호이스팅 때문에 변수 자체가 not defined는 아니지만 값이 undefined인 상태에서 콘솔에 출력된 것이다.

명백히 오류가 있는 코드인데 에러가 출력되지 않으니 코드 작성자는 undefined라는 단서 만으로 어디가 잘못 되었는지 파악이 어려울 수 있다. 이는 바람직한 동작이 아니다. let은 이 점을 보완한다.

일시적 사각지대(TDZ)

console.log(myName)
let myName = "Lee";
// Uncaught ReferenceError: myName is not defined

같은 코드를 let으로 작성하면undefined가 아닌 명확한 에러를 출력한다. 이것이 letvar의 약점을 보완하는 지점이다.

ES6의 let으로 변수를 선언하면, 변수에 값이 할당되기 이전까지 일시적 사각지대(TDZ)에 갇히도록 되어있다. 그러므로 값을 참조할 수 없으니 레퍼런스 에러가 발생한다.var를 사용했을 때와는 달리, 에러 메시지를 통해 오류를 쉽게 파악할 수 있으므로 완전히 var를 대체하도록 권장된다.

var의 운명


이미 var로 작성되어 있는 프로그램들이 있으니 var가 세상에서 완전히 사라지지는 않겠지만 쓰임 상 더 이상 필요하지 않다는 것이 중론이다.

const를 디폴트로 사용하는 것이 가장 확실하며, 재할당이 필요한 경우에 한해 let을 사용하는 것이 좋다.

🔗 노마드 코더 | ES6의 정석
🔗 let, const와 블록 레벨 스코프

좋은 웹페이지 즐겨찾기