본문 바로가기
Javascript

[ES6+] var vs let vs const

by kellis 2020. 10. 21.

prerequisite

 

Javascript에서 변수를 선언할 때 var를 사용하는 것은 익숙한 일이지만, let이나 const는 조금 낯설게 느껴집니다. 두 키워드가 ES6에서 새롭게 추가되었기 때문이라고 생각되는데, 이 글에서는 세 가지 키워드가 어떻게 다른지, 언제 어떤 키워드를 사용해야 하는지 알아보도록 하겠습니다. 

(1) var

var는 아래와 같은 특징을 가지고 있습니다. 

  • 함수 레벨 스코프 

변수의 유효 범위가 블록({}) 단위가 아닌 함수 단위입니다. 전역 함수 외부에서 변수를 생성하게 되면 이는 전부 전역 변수로 관리됩니다.

 

[함수 레벨 스코프]

var i, x, y;
for (i = 0; i < a.length; i++) {
    x = a[i];
    …
}
for (i = 0; i < b.length; i++) {
    y = b[i];
    …
}
 
var callbacks = [];
for (var i = 0; i <= 2; i++) {
    (function (i) {
        callbacks[i] = function() { return i * 2; };
    })(i);
}
callbacks[0]() === 0;
callbacks[1]() === 2;
callbacks[2]() === 4;

스코프가 함수 레벨이기 때문에 callbacks의 함수가 언제 실행될지 알 수 없고, 그 시점에 i가 어디에서 참조될지 알 수 없기 때문에, 원하는 대로 동작하게 만들어 주기 위해서는 위와 같이 즉시 실행 함수 내에서 function을 할당해주어야 합니다.

 

  • 변수 중복 선언 허용

변수의 중복 선언이 허용되기 때문에, 동일한 변수명으로 여러 차례 선언이 가능하며, 이 경우 의도치 않게 변수의 값이 변경되는 것을 확인할 수 있습니다. 

 

[함수 레벨 스코프 + 중복 선언]

var str = 'hello world - outside';
 
if(true){
    var str = 'hello world - inside';
}
 
console.log(str);   //result : hello world - inside
  • var 키워드 생략 허용 

var 키워드를 명시하지 않은 변수 선언이 즉시실행함수 내부에 존재할 경우, 이 변수를 바깥 스코프에서 찾는 시도를 수행합니다. 전역 스코프까지 찾아도 존재하지 않는다면, 자바스크립트 인터프리터는 전역 스코프 영역에 변수를 생성하게 되고 이는 전역 스코프를 오염시키게 됩니다. 

  • 호이스팅시 선언과 초기화가 한 번에 실행.  

var의 호이스팅은 선언과 초기화가 한 번에 실행되어 끌어올려지며, 할당은 끌어올려지지 않습니다.

 

[호이스팅]

console.log(str);   //undefined
var str = 'hoisting';
console.log(str);   //result : hoisting


그렇다면 let은 이러한 var의 단점을 어떻게 보완하였을까요? let은 아래와 같은 특징을 가집니다.

 

(2) let 

  • 블록 레벨 스코프

모든 코드 블록(if문, 함수, try/catch문 등) 내에서 선언된 변수가 그 블록 내에서 지역 변수처럼 동작하며, 블록 외부에서 접근할 수 없습니다. 대부분의 언어가 블록 레벨 스코프이며, 자바스크립트의 경우 함수 레벨 스코프를 지원합니다. 위에서 예제를 통해 보았듯 이로 인해 즉시 실행 함수를 사용하는 등의 번거로운 작업을 수행해야 하는데 let은 그렇지 않습니다. 

 

[블록 레벨 스코프]

for (let i = 0; i < a.length; i++) {
    let x = a[i]
    …
}
for (let i = 0; i < b.length; i++) {
    let y = b[i]
    …
}
 
let callbacks = []
for (let i = 0; i <= 2; i++) {
    callbacks[i] = function () { return i * 2 }
}
callbacks[0]() === 0
callbacks[1]() === 2
callbacks[2]() === 4
  • 변수 중복 선언 금지

var와 달리 let은 변수명을 재선언할 경우 에러가 발생합니다. 

 

[변수명 중복 선언 - let]

let str = 'first assign';
...
let str = 'second assign';
  • 호이스팅

let 역시 호이스팅이 됩니다. 그러나 var에서 보았던 것과는 조금 다르게 수행됩니다. 

var의 경우 변수의 선언과 초기화가 동시에 이루어지기 때문에 위에서 보았듯이 undefined가 출력되지만, let의 경우에는 선언과 초기화가 분리되어 진행됩니다. 그렇기 때문에 아래와 같이 ReferenceError가 발생합니다.

변수가 선언되어 호이스팅되어 있지만, 초기화는 실제로 선언이 이루어진 코드에 도착했을 때 이루어지게 됩니다. 

 

(3) const

const는 쉽게 말해 상수를 의미한다고 볼 수 있습니다. 재할당이 자유로운 let과 달리 const는 재할당이 불가능하며, 반드시 선언과 동시에 할당이 이루어져야 합니다. 다만 const는 할당된 값이 프리미티브 타입인가, 레퍼런스 타입인가에 따라 조금 다르게 사용되기 때문에, 단순히 상수라고 정의할 수는 없습니다.

const에 배열이나 객체, 함수 등의 레퍼런스 타입이 할당된다면 객체 내부의 식별자나 프로퍼티는 변경이 가능하기 때문입니다. 이러한 경우에 const를 사용하는 이유는 선언된 객체가 재할당되지 않도록, 즉, 처음 선언된 자료형을 그대로 사용하겠다고 명시해 주는 것입니다. 

 

[const에 객체 할당]

const const_test = function(){...};
 
const const_test = "re-assign by string valule";    //SyntaxError: Identifier 'const_test' has already been declared

Conclusion

세 키워드의 특징이 모두 다르기 때문에, 아래와 같은 사항을 고려하여 필요할 때 적절한 키워드를 사용하여야 합니다. 

  • ES6에서는 var의 사용을 지양한다
  • 재할당이 필요한 경우에만 let을 사용하고, 스코프를 최대한 작게 가지도록 작성한다.
  • 재할당이 필요하지 않은 경우 const를 사용한다. const는 재할당이 불가하기 때문에 var, let보다 안전하다. 

 

코드를 작성할 때, 이 변수가 재할당될 것인지 아닌지를 판단하기가 어려울 수도 있습니다. 추후에 어떻게 사용될지 알 수 없기 때문입니다. 그러므로 일단 const로 작성하고, 추후 변경할 일이 생긴다면 그때, const를 let으로 바꾸는 것을 권장합니다. 

 

 

 

[references]

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

 

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

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

medium.com

let, const와 블록 레벨 스코프

 

let, const | PoiemaWeb

ES5까지 변수를 선언할 수 있는 유일한 방법은 var 키워드를 사용하는 것이었다. var 키워드로 선언된 변수는 아래와 같은 특징이 있다. 이는 다른 언어와는 다른 특징으로 주의를 기울이지 않으면

poiemaweb.com

https://blueshw.github.io/2017/03/28/ES-var-VS-const-VS-let/

 

[ES6] var VS const VS let

ES6(ECMA Script 2015, 줄여서 ES6)로 넘어오면서 기존 ES5 까지 사용하던 변수 선언 키워드인 var에다 const와 let이라는 키워드가 추가되었습니다. 물론 var 없이도 변수를 선언할 수 있습니다만, 그렇게 ��

blueshw.github.io

http://es6-features.org/#BlockScopedVariables

 

ECMAScript 6: New Features: Overview and Comparison

Constants Constants Support for constants (also known as "immutable variables"), i.e., variables which cannot be re-assigned new content. Notice: this only makes the variable itself immutable, not its assigned content (for instance, in case the content is

es6-features.org

 

'Javascript' 카테고리의 다른 글

[Javascript] Closure  (0) 2020.10.21
[Javascript] 실행 컨텍스트  (0) 2020.10.21
[Javascript] Scope  (0) 2020.10.21
[requireJS] 전역 변수 오염을 어떻게 방지할까?  (0) 2020.10.21
[ES6+] Map vs Object  (2) 2020.10.21

댓글