티스토리 뷰

지난 포스팅에서 변수를 배웠습니다. var라고 하고 식별자를 쓰고 등호를 통해 값을 할당했습니다. 오늘은 에크마스크립트6(es6)를 통해 새롭게 추가된 let과 const를 다룰 예정입니다. 난이도가 좀 있으니 이해가 안되시면 그냥 넘어가시면 됩니다. 변수에 대한 전반적인 설명을 보시려면 아래 링크를 클릭해주세요.


var를 대체할 let과 const에 대해 알아보기



우선 let은 변수를, const는 상수를 의미한다는 것을 알아두셔야 합니다. var와 let, const는 각각 어느 차이가 있는지 지금부터 하나씩 알아보도록 하겠습니다. 실습은 콘솔창에서 진행하시면 됩니다.


var x = 3;
console.log(x + " : " + y);
var y = 7;


위의 소스코드를 콘솔창에서 실행하면 과연 어떤 값이 찍힐까요? 바로 3 : undefined입니다. 자바스크립트에서는 호이스팅이 일어납니다. 호이스팅이란 말그대로 들어올리는 것입니다. 저 코드가 실행되면 변수 y가 상단으로 끌어올려 집니다.


var x = 3;
var y;
console.log(x + " : " + y);
var y = 7;


실제로 위의 소스코드처럼 진행됩니다. 그래서 console.log(x + " : " + y)의 값이 3 : undefined로 나옵니다. 하지만 es6에 대해서 새롭게 변수를 나타낼 let과 상수를 나타낼 const는 이러한 호이스팅이 되지 않습니다. var를 let으로 바꾸면 에러가 뜨게 됩니다.


var는 호이스팅이 되지만, let과 const는 호이스팅이 되지 않습니다.


var는 함수에서만 범위가 있었습니다. 아래의 소스코드를 콘솔창에서 실행해보세요.


var z = 10;
var func = function(){
    var z = 20;
    console.log(z);
}
func();
console.log(z);


함수 안에서 z의 값을 새로 줬기때문에 z의 값이 변하지 않고 새롭게 만들어 졌습니다. 하지만 함수에서만 범위가 있다면 반복문이나 조건문 등에서 선언된 변수는 밖에서도 접근이 가능하다는 것을 뜻합니다. 


for(var i=0; i<3; i++){
    console.log(i);
}
console.log(i);
for(let j=0; j<3; j++){
    console.log(j);
}
console.log(j);


하지만 let과 const는 함수에서 뿐만 아니라 블록 레벨에서 범위를 가지기 때문에 마지막에 console.log(j)의 경우 에러가 뜨게 됩니다. 


var는 함수에서만 범위를 가졌지만, let과 const는 블록으로 범위를 가집니다.


var d = 10; var d = 9;


var의 경우 위의 소스코드처럼 재정의를 해도 딱히 문제가 없었습니다만, let과 const의 경우엔 같은 블록 레벨에서 이미 사용한 식별자는 다시 사용할 수 없습니다. 


let e = 5;
e = 3;


let으로 식별자 e에 5를 값으로 할당했다면 이제는 let을 제외하고 쓰는 것을 통해 값을 변경만 가능합니다. 


let과 const는 같은 블록 범위에서 이미 정의했다면 다시 정의할 수 없습니다.


값을 변경하는 것에 대해서 더 알아볼까요? var의 경우 미리 선언만 되는 경우들을 많이 보셨을 겁니다. var num; 등의 형태로요. let도 마찬가지로 let num;의 형태로 선언만 해도 가능합니다. 하지만 const의 경우 반드시 초기화해야합니다. 즉 const num = 10;의 형태로 맨 처음 선언되어야 합니다. 


const는 let과 var와 달리 선언만 해서는 안되고 초기화 해야합니다.


const에 대해서 더 알아봅시다. const는 상수니까 값이 할당되면 변경이 불가능하다고 생각하실겁니다. 그러나 이건 반만 맞았다고 할 수 있습니다. 콘솔창에 const c = 10;이라는 값을 주고 c를 다른 값으로 바꾸려고 하면 "Uncaught TypeError: Assignment to constant variable."라는 에러가 뜹니다. 하지만 const에 객체를 값으로 주었을 땐, 객체의 경우 주소가 식별자에 할당되기 때문에 새로 선언하지 않고, 안의 값을 변경하는 것은 가능합니다.


const lc = {name:"lemon"};
lc.name = "candy";
//객체에 대한 주소는 그대로고 안의 값만 수정
//했기때문에 변경됩니다.
const lc = {name:"lemon"};
//다시 선언해서 주소까지 바뀌기 때문에 에러가 납니다.


아직 객체에 대해서 배우지 않았으니 모르시는 분들은 그냥 넘어가셔도 상관없고, 혹시 이해가 되지 않으시는 분들은 const로 객체를 선언하면 변경이 가능하다고 기억해주세요.


const의 값으로 객체를 줄 때는 객체가 있는 주소와 연결되기 때문에 값 변경은 가능하지만 새로 선언할 경우는 에러가 뜨게 됩니다.


alert()는 괄호 안에 있는 내용을 경고창을 통해서 보여주는 함수입니다. 이까지 읽으신 분들이라면 당연히 알만한 내용입니다. 그런데 var를 통해서 alert에 새로운 함수를 넣어준다면 어떻게 될까요?


var alert = function(){
    console.log("empty")
};
alert();


이런 경우 전역객체에 있던 alert()라는 메소드에 새 메소드가 덮어씌워집니다. 즉 위의 소스코드로 입력한 alert()가 window.alert()가 되고, 경고창을 띄우는 기능이 사라지게 된 겁니다. 하지만 let이나 const를 통해서 선언하게 되면 전역 스코프는 맞지만 전역객체를 덮어씌우지는 않습니다. 즉 window.alert()라는 경고창을 띄우는 기능도 살아있고, alert()를 실행하면 콘솔창에 "empty"가 찍히게 됩니다.


let이나 const는 전역스코프를 갖더라도 전역객체(window)의 프로퍼티는 되지 않습니다. 


쓰다보니 아주 길어졌습니다. 마지막으로 let과 const가 var의 역할을 대체하게 되면 언제 let을 사용하고, 또 언제 const를 사용해야 할까요? 현재 가장 좋은 방법은 기본적으로 const를 사용하라는 것입니다. 그리고 값이 바뀌는 변수에 대해서만 let을 사용하면 됩니다.



이상으로 변수에 대한 포스팅을 마치겠습니다.



공감은 제작자에게 큰 힘이 됩니다. 


댓글