본 포스팅은 JavaScript에서 const 키워드를 사용하는 경우를 소개합니다.
개요
JavaScript에서 변수를 선언할 때, var, const, let 중 어떠한 키워드를 사용해야할지 고민이 될 경우가 있다. 과거 웹 브라우저에서는 const, let 키워드를 지원하지 않았기에 var 키워드만 사용할 수 있었다. 그러나 2015년 ES6라고 알려진 ECMAScript6에서 var 키워드의 문제점을 개선한 const, let 키워드를 제공한다.
ES6에서 제공하는 const 키워드는 블록({}) 범위에서 상수를 선언하기 위해 사용되며, const로 선언된 변수는 초기화 후 값을 변경할 수 없다.
const a = 10;
a = 20; // Uncaught TypeError: Assignment to constant variable.
그리고 아래와 같이 const 키워드로 선언된 변수에 값을 초기화하지 않으면 SyntaxError가 발생한다.
const a; // Uncaught SyntaxError: Missing initializer in const declaration
const 키워드를 사용하는 상황
상수는 변하지 않는 값을 의미한다. 대부분의 프로그래밍 언어에서 변하는 값인 변수와 변하지 않는 값인 상수를 구분하기 위해 상수를 대문자로 작성하는 관습이 있다.
1. 수학적인 상수
const PI = 3.14;
PI의 3.14처럼 변경되지 않는 고정 값을 const 키워드로 선언할 수 있다.
2. 고정 값
const DAYS_IN_WEEK = 7;
const HOURS_IN_DAY = 24;
주당 일수와 하루의 시간 수를 상수로 선언할 수 있다.
const 키워드로 선언된 상수는 불변인가?
const 키워드로 선언된 변수가 불변(변하지 않음)을 의미하는 것은 아니다.
다음과 같이 const 키워드로 선언된 변수 user에 객체를 초기화한 다음 다른 객체를 할당하면 TypeError가 발생한다.
const user = {name: "John"};
user = {age: 20}; // Uncaught TypeError: Assignment to constant variable.
하지만, 다음과 같이 user 객체의 프로퍼티를 변경하는 것은 가능하다.
const user = {name: "John"};
user.name = 'Bob';
console.log(user.name); // Bob
객체 및 배열과 같은 참조 타입의 변수에는 실제 값이 아닌 메모리 주소가 저장되며, 객체의 프로퍼티를 변경하는 경우 메모리 주소를 통해 실제 값을 변경하기 때문이다.
const 키워드를 사용하는 이유
위에서 const 키워드를 사용하는 “상황”에 대해 설명했다면, 이번에는 const 키워드를 사용하는 “이유”를 설명한다.
1. 코드 가독성 향상
const 키워드로 선언된 변수는 상수를 의미하므로 코드를 공유하는 경우 다른 개발자들에게 코드의 의도를 더 명확하게 전달할 수 있다.
만약에 다음과 같이 수학적인 상수 PI를 var 혹은 let 키워드로 선언한다고 가정해보자.
let PI = 3.14;
변수의 이름이 대문자인데, let으로 선언되어 “PI의 값이 변할 수 있나?”라는 의문을 가질 수 있다. 코드의 의도가 명확하지 않으므로 혼란을 가중시키고 최악의 경우 변수 PI의 값을 변경하여 의도하지 않은 결과를 초래할 수 있다.
2. 호이스팅 현상 완화
Java, C#과 같은 정적 타입의 프로그래밍 언어는 변수를 선언한 다음 변수를 접근할 수 있다. 하지만, JavaScript에서는 다음 예시처럼 변수를 접근한 다음 변수를 선언할 수 있다.
console.log(age); // undefined
var age = 30;
이러한 동작을 호이스팅이라고 말한다. 코드가 실행되기 전에 JavaScript 엔진에 의해 변수와 함수가 메모리에 먼저 할당되고 코드가 실행되기 때문에 에러가 발생하지 않는다. 주의할 점으로 변수는 선언만 메모리에 할당되고 초기화 값은 메모리에 할당되지 않는다. 따라서, console.log(age)에서 30을 출력하지 않고 undefined를 출력한다.
그러나 const, let 키워드로 선언한 변수는 var 키워드로 선언한 변수와 다르게 호이스팅 된다.
console.log(age); // Uncaught ReferenceError: Cannot access 'age' before initialization
const age = 30;
var 키워드로 선언된 변수와 달리 변수 age에 값이 초기화 전에 접근했다는 ReferenceError가 발생한다. const 키워드로 선언된 변수는 선언과 초기화가 동시에 되어야 하는데, JavaScript 엔진에 의해 변수의 선언만 메모리에 할당되고 초기화 값은 할당되지 않아 ReferenceError가 발생한다. 이러한 현상을 Temporal Dead Zone (TDZ)이라고 말하는데, 변수가 호이스팅 되었지만 접근(참조)할 수 없는 현상을 의미한다.
따라서, const 키워드로 변수를 선언하면 변수를 접근하기 전에 값이 할당되었는지 확인할 수 있으므로 개발자는 안정적인 코드를 작성할 수 있다.
Conclusion
- 웹 브라우저에서 ES6를 지원하지 않으면 var 키워드를 사용하여 변수를 선언하고, ES6를 지원하면 var 대신 const, let 키워드를 사용하여 변수를 선언한다.
- const 키워드로 상수를 선언할 수 있지만 배열, 객체와 같은 참조 타입의 값은 변경할 수 있으므로 불변을 의미하는 것은 아니다.
- var 키워드로 선언된 변수는 호이스팅될 때, undefined로 초기화되지만 const, let 키워드로 선언된 변수는 초기화없이 호이스팅된다.
- 결론적으로 const, let 키워드는 var 키워드에 대한 대안으로 도입되었다.
참고
- Hoisting in JavaScript with let and const – and How it Differs from var
- https://medium.com/dailyjs/use-const-and-make-your-javascript-code-better-aac4f3786ca1