개요
카카오 코딩테스트 문제를 풀다가 임의 객체 A를 배열B에 Push한 후 객체 A의 내용을 바꿨는데 배열B에 Push 되어 있던 객체 값이 바뀐 결과가 발생했다. 이 때 나는 배열에 push한 값은 value로 들어간다고 착각했고, 설마 주소값이 들어가는 것 인가? 예상해보았지만 그 결과는 정확히 맞았다.
이미 선언된 객체를 변하지 않는 불변 객체로 만들면 되지 않을까? 라는 생각에 불변 객체에 대해 알아보고 남기는 포스팅이다.
(코딩테스트 문제에서는 이 방법을 사용하지는 않았지만...)
불변 객체
먼저 불변(immutability)이란 뭘까? 단어에서 유추해볼 수 있다시피 '변하지 않는' 뜻이라고 생각하면 되겠다.
그럼 '불변 객체'란? '변하지 않는 객체' 즉 이미 할당된 객체가 변하지 않는다는 뜻을 가지고 있다.
자바스크립트에서 불변 객체를 만들 수 있는 방법은 기본적으로 2가지 인데 const와 Object.freeze()를 사용하는 것이다.
const
자바스크립트 키워드 중 하나인 const이다. ES6문법부터 let과 const를 지원한다.
const 키워드는 변수를 상수로 선언할 수 있다, 일반적으로 상수로 선언된 변수는 값을 바꾸지 못하는 것으로 알려져 있다.
그렇다면 상수로 선언한 객체는 불변 객체일까?
const test = {};
test.name = "mingyo";
console.log(test); // {"mingyo"}
ES6에서의 const는 할당된 값이 상수가 되는 것이 아닌 바인딩된 값이 상수가 되는, 즉 test변수가 상수가 되기 때문에 const 키워드로 선언된 test변수에는 객체 재할당은 불가능하지만 객체의 속성은 변경 가능하다.
재할당이 불가능 한 이유는 변수와 값(객체) 사이의 바인딩 자체가 변경이 되기 때문에 상수인 test변수는 재할당이 불가능한 것이고
객체의 속성이 변경가능 한 이유는 실제 객체가 변경은 되지만 ( {} -> name : "mingyo" ) 객체와 변수(test)사이의 바인딩은 변경이 되지 않기 때문에 객체의 속성은 변경가능한 것이다.
때문에 비록 재할당은 불가능하지만 객체의 속성을 변경함으로 인해 변수에 바인딩된 객체의 내용까지 변경이 되기 때문에 불변객체라고 하기는 힘들다. 따라서 Object.freeze()라는 JS내장메소드도 살펴보도록 하겠다.
Object.freeze()
자바스크립트에서 기본적으로 제공하는 메소드인 Object.freeze() 메소드이다. 공식 문서에서는 "객체를 동결하기 위한 메소드" 라고 적혀있다.
그렇다면 이 메소드를 사용하면 불변 객체를 만들 수 있을까?먼저 이 메소드의 사용법부터 알아보면,
let test = {
name : 'kim'
}
Object.freeze(test);
사용법은 간단하다. test 변수에 key value를 가진 객체를 바인딩 후 Object.freeze(test)를 사용해 바인딩된 변수를 동결 객체로 만들었다. 때문에 test 객체는 객체의 속성을 변경하는 시도는 불가능하다.
test.name = 'Jung';
console.log(test) // {name: 'kim'}
위와 같이 객체의 속성을 변경하는 시도는 무시된다.
그러나 Object.freeze()는 동결된 객체를 반환하지만 객체의 재할당은 가능하다.
test = {
age : 15
};
console.log(test); // {age: 15}
위와 같이 객체의 재할당은 가능하다. 때문에 Object.freeze()도 불변 객체라고 할 수는 없을 것 같다.
그럼 결국 불변 객체는 어떻게 만들 수 있냐면..
const와 Object.freeze()를 조합하여 만들 수 있다. (const의 재할당불가 + Object.freeze()의 객체속성 변경불가)
그렇다면 아래 코드와 같이 사용하면 된다.
const test = {
'name' : 'jung'
};
Object.freeze(test);
먼저 const키워드로 바인딩 된 변수를 상수화 시킨 다음, Object.freeze()로 해당 변수를 동결 객체를 만들면
객체의 재할당과 객체의 속성 둘 다 변경불가능한 불변 객체가 된다.
참고 포스팅
'웹프로그래밍 > JavaScript' 카테고리의 다른 글
[JavaScript] 구조 분해 할당(Destructuring Assignment) (0) | 2022.07.07 |
---|---|
[JavaScript] 표준 내장객체 정리(상시 업데이트) (0) | 2022.06.03 |
[JavaScript] 프로토타입(Prototypes)의 이해 (0) | 2022.02.25 |
[JavaScript] 호이스팅(Hoisting) (0) | 2021.12.30 |