JS - let과 const
이전 Javascript 포스팅인 Block Scope에 이어서 ES6의 let과 const에 대해서 정리합니다.
let
재할당 가능
let은 재할당이 가능하다.
let a = 1
a = 2
console.log(a)
반복문 내에서의 함수 실행시
var의 경우, for문 내에서 함수를 실행하면 첫 번째 예시와 같이 의도와 달리 오작동한다. 때문에 두 번째 예시처럼 즉시실행함수(IIFE)로 감싸서 각각의 i를 직접 넘겨줘야 정상 출력되었다. 하지만 let의 경우에는 Block Scope를 가지기 때문에 그럴 필요가 없다.
/* var의 문제 */
var funcs = []
for (var i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
});
}
funcs.forEach(function (f) { // 의도와 달리 10이 10번 출력
f()
})
/* var의 문제를 IIFE로 해결 */
var funcs = []
for (var i = 0; i < 10; i++) {
(funcs.push(function () {
console.log(i)
}))(i);
}
funcs.forEach(function (f) { // 0 ~ 9 순차대로 정상 출력
f()
})
/* let의 block scope로 인한 근본적인 해결 */
let funcs = []
for (let i = 0; i < 10; i++) {
funcs.push(function () {
console.log(i)
})
}
funcs.forEach(function (f) { // 0 ~ 9 순차대로 정상 출력
f()
})
const
재할당 불가
const는 constant variable의 약자이며 상수 변수라는 의미를 가진 말그대로 상수이기 때문에 재할당이 불가능하다.
const PI = 3.141593
PI = 3.14 // Error
선언시에 할당
const는 선언과 동시에 할당해줘야한다. 그렇지 않으면 에러가 발생한다.
const PI; // Error
참조 타입 데이터
상수 변수인 const에 참조 타입의 데이터를 할당하면 const의 내부 property는 상수가 아니다. 다시말해 내부 property는 변경이 가능하다. 이해를 위해 아래의 그림과 예시를 보자.

const OBJ = {
a: 10,
b: 20
};
obj1 = 30; // Error - 변경 불가
OBJ.a = 30;
console.log(OBJ); // {a: 30, b: 20} - property a값 변경 가능
OBJ가 할당된 주소값은 상수이고 내부 property는 상수가 아니다. 때문에 예시에서 OBJ.a의 값을 변경할 수 있다.
내부 property도 상수로 만들기 위해서는?
상수에 할당된 참조 타입 데이터 내부 property도 상수로 만들기 위해서는 Object.freeze()와 Object.defineProperty()라는 Object의 메소드를 사용하는 방법이 있다.
const OBJ1 = {};
Object.defineProperty(OBJ1, 'a', {
value: 10,
writable: false,
configurable: false
});
OBJ1.a = 200; // Error - 변경 불가
const OBJ2 = {
a: 30,
b: 40
};
Object.freeze(OBJ2)
OBJ2.a = 100; // Error - 변경 불가
참조 타입 데이터를 중첩하고 있으면?
const OBJ3 = {
a: 10,
b: 20,
c: [1, 2, 3, 4, 5], // 참조 타입 데이터인 배열
};
Object.freeze(OBJ3)
OBJ3.a = 100; // Error
OBJ3.c.push(6);
console.log(OBJ3.c); // 6이 추가됨(변경 가능)
상수에 참조 타입 데이터의 내부 property가 또 참조 타입 데이터이면 Object.freeze() 메소드를 사용하더라도 변경 가능하다. Object.freeze() 메소드는 참조 타입 데이터를 반영하지 못하기 때문이다.
이처럼 중첩된(Nested) 참조 타입 데이터의 경우에는 다음과 같이 해결 해야한다.
OBJ3를Object.freeze()메소드로 얼린다.OBJ3의내부 property를 순회하면서 해당property가 참조 타입이면 1번을 반복한다.
이 과정을 재귀를 통해서 구현하면 모든 내부 property도 변경할 수 없는 완전한 상수를 만들 수 있다. 이를 DeepFreeze라고도 한다. 이 방법은 추후에 정리할 깊은 복사(Deep Copy)에서도 동일하다.
반복문 내부의 상수
for문 내부에서 const를 사용했을 때 for in 문 같은 경우에 생각해보면 상수에 재할당 되기 때문에 Error가 날 것 같지만 이상하게 정상동작한다. 하지만 for문의 경우에는 재할당이 되지 않아서 0을 한번 출력하고는 Error가 발생한다. 뭔가 일괄적이지 않은 느낌이지만 알고는 있자.
let obj = {
a: 10,
b: 20,
c: 30,
};
for (const a in obj) {
console.log(a); // a, b, c 출력 - 정상 동작
}
for (const i = 0; i < 10; i++) {
console.log(i); // 0 출력 후 Error
}
TIP. 주로 객체를 다루는 FE환경에서는
const를 잘 사용하지 않을 뿐만 아니라 클린 코드를 위해서let보다는 최대한const를 사용도록 노력하자.
전역 객체의 property
전역 공간에서 var가 선언되면 전역 변수와 전역 객체의 property가 동시에 할당되었다. 하지만 let과 const는 더이상 전역 객체의 property가 되지 않고 오직 전역 변수로 할당된다.
var a = 10;
console.log(a) // 10
console.log(window.a) // 10
delete a; // false
delete window.a; // false
console.log(a) // 10
console.log(window.a) // 10
let b = 20;
console.log(b) // 20
console.log(window.b) // undefined ----- 전역 객체의 property가 아님
delete b; // false --------- 전역 객체의 property가 아니기 떄문에 삭제 불가
delete window.b; // true ---------- undefined라서 true
console.log(b) // 20
console.log(window.b) // undefined
위의 예시를 보면 let의 경우에 전역 객체의 property(window.b)가 아닌 전역 변수(b)에만 할당되고 있음을 확인할 수 있고 const도 마찬가지로 동일하게 동작한다.
참조
Author And Source
이 문제에 관하여(JS - let과 const), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@leo-xee/JS-let과-const저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)