게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌2 - ECMAScript - 8년 전 등록 / 6년 전 수정

ES2015(ES6) Const, Let

안녕하세요. 이번 시간부터 본격적으로 ES2015(ES6)에서 어떻게 자바스크립트가 바뀌었는지 알아보겠습니다!

먼저 변수를 선언할 때 var 외에도 const(constant, 상수)와 let이 생겼습니다.

const, let

기존 var과의 가장 큰 차이점은, const와 let은 함수스코프를 따르지 않고 블록스코프를 따른다는 겁니다. 스코프를 잘 모르신다면 이 글을 참고하세요. 지금까지 자바스크립트는 다른 언어와는 다르게 함수스코프를 사용하여 다른 언어를 사용하는 사람들이 적응하기가 힘들었는데, const와 let이 도입되어 적응하기 좀 수월해졌습니다.

블록스코프란 해당 변수를 해당 블록에서만 접근할 수 있는 것을 말합니다. var은 블록스코프가 아닌 함수스코프라서 if 블록과는 상관없이 접근할 수 있지만, const와 let은 블록 바깥에서는 접근할 수 없습니다.

if (true) {
  var x = 3;
}
console.log(x); // 3
if (true) {
  const y = 3;
}
console.log(y); // Uncaught ReferenceError: y is not defined

const와 let에서도 호이스팅이 일어나지만, var에서 일어나는 호이스팅과는 조금 다릅니다. var은 hoisting 때문에 코딩할 때 예기치 못한 상황이 자주 발생했죠. 변수를 선언한 곳보다 더 위에서 해당 변수에 접근할 수 있는 경우가 있었습니다. const와 let을 사용할 때는 선언한 곳보다 위에서 접근하는 것이 금지됩니다(에러 발생).

사실 호이스팅은 정의가 불분명한 용어입니다. 스펙에는 없지만 자바스크립트 동작을 설명하기 위해 만들어진 용어입니다. const와 let에도 호이스팅이 있다고 볼 수도 있습니다만, 호이스팅의 정의가 정해진 것이 아니라서 맞다 틀리다 판단할 수 없습니다. 그냥 const와 let은 var의 호이스팅과는 다르게 동작하며, TDZ(Temporal Dead Zone)이라는 현상을 갖고 있다고 알아두시는 게 좀 더 정확할 수 있습니다.

다음의 상황은 변수를 선언하기 전에 변수에 접근했는데도 에러가 나지 않는 현상을 보여줍니다.

(function() {
  console.log(x);
  var x = 10;
})(); // undefined;

하지만 const와 let은 그 현상을 차단했기 때문에 더 이상 변수를 선언한 곳보다 위에서는 변수에 접근이 불가능합니다.

(() => {
  console.log(z);
  const z = 10;
})(); // Uncaught ReferenceError: z is not defined

const와 let은 전역 스코프에서 선언 시 var과는 다르게 window나 global에 등록되지 않습니다.

var m = 1;
console.log(window.m); // 1
const n = 2;
console.log(window.n); // undefined

둘의 차이

const와 let의 차이는 간단합니다. 둘다 블록스코프를 따르지만, const는 한 번 초기화하면 다른 값을 대입할 수 없습니다. let은 기존의 var처럼 계속 값을 바꿔줄 수 있고요. const를 사용하면 절대 바꿔서는 안 되는 값을 실수로 바꾸는 것을 예방할 수 있겠죠?

const a = 100;
a = 101; // Uncaught TypeError: Assignment to constant variable.
let b = 100;
b = 101; // 101

하지만 조심해야 할 점은, const는 다시 대입하는 것만 막지, const에 할당된 객체나 배열의 요소를 바꾸는 것은 막지 않습니다. 즉 데이터의 주소값만 고정하는 겁니다.

const c = [1, 2, 3];
c[0] = 4;
c; // [4, 2, 3]
const d = {name: 'Zero'};
d.name = 'One';
d; // {name: 'One'} 

즉, =을 통한 대입만 막은 거죠. 이제 var 외에도 선택지가 두 개나 더 생겼으니 상황에 따라 선택하면 될 거 같습니다! 사실상 이제 var은 사용할 일이 없습니다. var의 기능은 let이 다 하거든요. const는 좀 더 제한적인 상황에서 사용하는 것이고요.

다음 시간에는 object의 변화에 대해 알아보겠습니다! 

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

2개의 댓글이 있습니다.
6년 전
내용 잘보고 있습니다.
출처 밝히고 내용 일부 참조해도 괜찮을까요?
6년 전
네 됩니다~
6년 전
안녕하세요! 나름 파급력이 있는 블로그라고 생각되서 댓글 남기게 되었습니다 :)
const와 let 키워드로 변수를 선언할 때도 var 키워드를 사용하여 변수를 선언하는 것과 마찬가지로 호이스팅이 일어납니다!!
6년 전
tdz 말씀하시는거죠? 그걸 호이스팅이라고 볼 수 있는지는 잘 모르겠습니다.
6년 전
호이스팅의 정의가 무엇인가요?
6년 전
정의가 내려지지 않은 용어라서요. 스펙에도 호이스팅이란 단어가 없는 것으로 알고있어요.
6년 전
아, 맞습니다! 스펙 문서에는 중간 중간 hoisted 정도로만 언급이 되고 그나마 mdn 문서에 호이스팅이라는 용어 설명만 나옵니다. 제가 드린 질문은 위 현상을 호이스팅이라고 보지 않는다고 하셨는데, 어떠한 의미로 호이스팅을 말씀하셨는지가 궁금해서요! 나름 생각하고 계신 정의가 있을 것 같아 여쭤봤습니다. 그렇게 되면 호이스팅이 일어나지 않는다라는 말이 맞을 수가 있기 때문입니다 :)
6년 전
JavaScript는 초기화가 아닌 선언만 끌어올립니다(hoist).라고 MDN에 되어있는데요. var이나 function같은 것이 위로 끌어올려진 것 마냥 동작한다는 것이죠.
그런데 const랑 let이 위로 끌어올려진 것 마냥 동작한다고 하기에는 에러가 발생합니다. 이 에러는 TDZ라는 개념 없이는 설명하기 힘든 것 같아요. 즉, var와 같은 호이스팅이 아니라고 말할 수 있겠네요.
호이스팅의 정의가 명확하지 않다는 점과 TDZ를 언급하도록 포스트를 수정하였습니다.
6년 전
덧붙이자면 변수, 함수들이 `hoisted` 되는 것은 메모리 할당을 위해서 이고, 이는 브라우저 자바스크립트 엔진이 자바스크립트를 파싱하는 과정 중 하나의 단계입니다. 때문에 hoisted는 되지만 ecmascript spec에서 `not be accessed in any way until the variable’s LexicalBinding is evaluated`라고 표현되어 있는 temporary dead zone을 만들어 선언 전 접근을 막습니다 :)

빠른 반영 감사드리며, 늘 좋은 글 잘 보고 있습니다~
6년 전
방금 놀라운 걸 발견했는데요. let을 설명하는 한글 MDN에서는 호이스팅이 일어나지 않는다고 되어있고, 영어 MDN에서는 호이스팅이 일어난다고 되어있네요. 뭔가 번역 상에서 실수가 발생한 것인지도 모르겠습니다. 블로그 설명은 영어 MDN에 따라 호이스팅이 일어난다고 바꾸었습니다.

좋은 의견 남겨주셔서 감사드리고, 잘못된 설명이 있다면 언제든지 지적해주세요. 방문자가 많이 늘어나서, 잘못된 정보를 올리지 않을까 걱정되네요.