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.)