💡 es6에 들어와서
const
와let
이 추가 되었다.
var
[es5]const
[es6]let
[es6]
const
,let
은 기존의var
의 문제점을 해결하기 위하여 추가 되었고
그에 따른 특성을 가진다.모던 자바스크립트에서는 가능한
const
,let
의 사용을 지향한다.
var
재선언 및 재할당 모두 자유롭다.
const
재선언 과 재할당이 불가능 한 상수.
let
재선언은 불가능하지만 재할당은 가능하다.
var
var varName = '기본';
console.log("varName 기본 : ", varName);
// var 재할당
varName = '재할당';
console.log("varName 재할당 : ", varName);
// var 재선언
var varName = '재선언';
console.log("varName 재선언 : ", varName);
// varName 기본 : 기본
// varName 재할당 : 재할당
// varName 재선언 : 재선언
var
의 경우 변수의 선언 및 할당이 자유롭다.
const
& let
const constName = '기본';
let letName = '기본';
console.log("constName 기본 : ", constName);
console.log("letName 기본 : ", letName);
// constName 기본 : 기본
// letName 기본 : 기본
// 재할당
letName = '재할당';
console.log("letName 재할당 : ", letName);
constName = '재할당';
console.log("constName 재할당 : ", constName);
// letName 재할당 : 재할당
// TypeError: Assignment to constant variable.
let letName = '기본';
console.log("letName 기본 : ", letName);
// letName 기본 : 기본
// 재선언
let letName = '재선언';
console.log("letName 재선언 : ", letName);
// SyntaxError: Identifier 'letName' has already been declared
const
재할당 시 TypeError: Assignment to constant variable. 오류 확인 가능.
let
및 const
재선언 시 SyntaxError: Identifier 'letName' has already been declared 오류 확인 가능.
var
는 function scope 로서 유효범위가 함수( function ) 범위 이다.
let
과 const
는 block scope 로서 유효범위가 block( { } ) 범위 이다.
var varNum = 1;
let letNum = 2;
if (true) {
var varNum = 100;
let letNum = 200;
console.log('varNum = ', varNum); // 100
console.log('letNum = ', letNum); // 200
}
function doSomething() {
var varNum = 1000;
let letNum = 2000;
console.log('varNum = ', varNum); // 1000
console.log('letNum = ', letNum); // 2000
};
doSomething();
console.log('varNum = ', varNum); // 100
console.log('letNum = ', letNum); // 2
먼저 if
블록 내부에 선언된 변수를 확인해 let
이나 const
의 경우 유효범위가 block scope 이기 때문에 블록 내부에 선언된 변수가 출력된다. var
의 경우 블록 내부에 재선언되었다고 하더라도 전체적인 function scope 범위는 그대로 이기 때문에 역시 블록 내부의 변수가 출력된다.
doSomething
함수 내부에 선언된 변수의 경우 변수 종류 (const
, let
, var
)에 상관없이 함수 내부에서 찾은 변수를 출력 한다.
마지막으로 출력되는 결과 값을 보면 function scope 와 block scope 간의 차이를 볼 수 있다. doSomething
함수 내부에 선언된 변수는 함수의 종료후 유효 범위가 종료되었기 때문에 var
와 let
모두 출력 결과에 영향이 없으며 그 이전에 선언된 값에 따라서 출력 결과에 차이가 있다.
var
선언에는 Hoisting 이라는 문제점이 존재한다.
Hoisting 은 변수의 선언을 함수의 최상단 으로 끌어올리는 동작을 말한다.
console.log(varNum); // undefined
var varNum = 1;
console.log(varNum); // 1
첫번째 출력 결과를 보면 예상 했던 ReferenceError 대신 undefined 이 출력되되었다. 이는 Hoisting 을 통하여 변수의 선언부가 함수의 상단으로 이동되었다는 것을 알 수 있다.
이를 코드로 변환하면 다음과 같을 것이다.
var varNum;
console.log(`${varNum}`); // undefined
varNum = 1;
console.log(`${varNum}`); // 1
문제는 이러한 Hoisting 때문에 의도치 않은 동작이 발생 할 수 있다.
for(var i = 0 ;i < 10 ;i++) {
// ...
}
console.log(i); // 10
예상 했던 ReferenceError: i is not defined 오류 대신 for
반복문 내부에 index 용도로 선언된 변수의 최종 값이 출력 되었다.
이러한 문제들 때문에 가능한 var
대신 const
와 let
을 사용하는 것을 권장 하고 있으며. 불가피하게 var
을 사용할 경우 엄격 모드 ('use strict';) 또는 모듈화(es6)를 사용하여 해당 실수들을 에러로 핸들링 하도록 권장한다.
엄격 모드 적용시 최악의 경우라도 기존 소스에는 영향이 없다!!
💬 정리
var
대신 let
과 const
를 사용하자!