본문 바로가기
IT/자바스크립트

[javascript] ES6 반드시 알아야 할 문법 let, const의 공통적인 특징 5가지

by 모찌 2018. 8. 23.

es5 에서 var는 유일하게 변수를 선언할 수 있는 키워드였다. var는 무척 너그러운 선언이므로 사용하려면 철저한 설계가 필요했다.  그렇지 않다면 심각한 문제를 초래할 수 있다.


이러한 문제들을 보완하려 es6에서는 let과 const 문법을 정의했다.


let과 const 특성을 var와 비교하면서 알아보자


let과 const의 공통적인 특성이므로, 예제는 let을 이용해 작성했다.


1.   중복 선언 불가


var는 중복 선언이 가능하다. 다음과 같은 코드에서는 error가 발생하지 않는다.


var varValue =1;
var varValue =2;


let은 다음과 같이 이미 선언된 변수라는 Syntax Error가 발생 된다.


let letValue  = 1;
let letValue = 2; //Uncaught SyntaxError: Identifier 'letValue' has already been declared


그렇다면 같은 변수명으로 var로 선언하고 let을 선언하면 어떻게 될까.

이 역시 Syntax Error가 발생 된다.

var value;
let value; //Uncaught SyntaxError: Identifier 'letValue' has already been declared



2. 전역 객체와의 관계


var를 전역 변수로 선언하면 전역 객체의 프로퍼티로 된다.


var varValue =1;
console.log(window.varValue); // 1


하지만 let으로 선언한다면 전역 객체의 프로퍼티로 되지 않는다.

let으로 전역변수로 선언한다면 해당 변수는 전역에서 보이지 않는 블록 내에 존재하는 것이다.


let letValue =1;
console.log(window.letValue); // undefined



3. 블록 레벨 스코프


기존의 var로 선언한 변수는 함수 레벨 스코프(function-level scope)를 갖는다.

하지만 let으로 선언한 변수는 블록 레벨 스코프(block level scope) 갖는다. 


함수 레벨 스코프 : 함수 내에서 선언한 변수는 함수 내에서만 유효하다. 함수 외부에서 참조가 불가능하다.

블록 레벨 스코프 : 코드 블록 { }을 기준으로 블록 내부에서 선언한 변수는 블록 내에서만 유효하다. 


다음 코드를 보자.


{
var varValue = 1;
let letValue = 1;
}

console.log(varValue);
console.log(letValue); //Uncaught ReferenceError: letValue is not defined


위의 코드에서 변수는 { } 사이에 선언되어 있다. var로 선언한 변수는 함수 레벨 스코프를 갖기 때문에 위 코드에서는 함수가 아닌 블록 내에서 선언한 것이므로 전역 변수로 선언한 것 같다. 하지만 let은 블록 레벨 스코프를 갖기 때문에 지역 변수가 되는 것이다. 즉, 외부에서 참조가 불가능하므로 Reference Error 가 발생되는 것이다.



4. 호이스팅


호이스팅이란, var, function 등의 선언문을 해당 스코프의 최상위로 끌어올려서 선언 및 초기화하고 할당 받는 곳에서 값을 할당받는 현상을 말한다. 

다음과 같이 var로 선언된 것 변수를 선언하기 전에 미리 참조해보자.

  

console.log(varValue); //undefined
var varValue = 1;


이 코드는 호이스팅에 의해 결국 다음 코드와 같다.


var varValue;
console.log(varValue); //undefined
varValue = 1;


변수는 선언과 undefined로 초기화는 되었으나 할당 받지 않았으니 undefined가 발생된다.

let으로 선언하여 확인해보자


console.log(letValue);   //Uncaught ReferenceError: letValue is not defined
let letValue = 1;


let으로 선언한 변수는 Reference Error가 발생한다. 

let으로 선언한 변수는 호이스팅이 적용되지 않는다. let으로 선언하면 블록 시작되는 부분부터 선언이 실행되기 전까지 일시적 사각지대(Temporal Dead Zone, TDZ)


구간이 생기게 되는데 이 구간에서는 참조가 불가능하다. 그러므로 Reference Error가 발생하게 되는 것이다.


5. 클로저


우선 다음 코드를 보자

var x = [1, 2, 3];
for (var i = 0; i < x.length; i++) {
setTimeout(function () {
console.log(x[i]);
}, 10);
}

이와 같은 코드에서 i는 전역 변수로 선언되기 때문에 i를 마지막 i++까지 진행하여 3으로 할당된다.

그렇다면 i는 3으로 함수가 실행되며 log에는 x[3]인 undefined가 3번 출력된다.


내가 원하던 결과를 얻기 위해서 클로저를 사용해서 코드를 수정해보자.

var x = [1, 2, 3];
for (var i = 0; i < x.length; i++) {
setTimeout(function () {
console.log(x[i]);
}(i), 10);
}

위와 같이 수정을 하게되면 1 2 3 이 출력된다.


이 문제는 i를 let으로 선언 하면 간단해진다.

var x = [1, 2, 3];
for (let i = 0; i < x.length; i++) {
setTimeout(function () {
console.log(x[i]);
}, 10);
}

let으로 선언하면 똑같이 1 2 3 이 출력된다.

(위 코드에서는 for문 안에 const로 선언하는 것이 불가능하다. 그 이유는 다음 포스팅에서 설명한다.)



이번 포스팅에서는 let과 const 의 특징을 var와 비교하면서 알아봤다. 

다음 포스팅에서는 let과 const 차이점에 대해서 알아보도록 하자.


댓글