이끌든지 따르든지 비키든지

Software Development/JavaScript

[JavaScript] const의 불변성

SeongHo5 2023. 9. 16. 22:12

자바스크립트에서 const는 상수, 즉 불변형 변수를 선언할 때 사용한다. 자바의 final과 같은 역할을 하는 키워드인 셈인데,

const로 선언된 객체를 Java에서 final로 선언된 객체와 같이 Read-Only라고 생각할 수 있지만, const로 선언된 객체의 속성은 변경할 수 있다. 그럼 Read-Only가 아니라는 건가?


예시 코드를 통해 알아보자면,

const person = {
  name: 'John',
  age: 30
};

person.age = 31;

console.log(person); // 출력: { name: 'John', age: 31 }

 

위 코드처럼, person의 속성인 age는 변경이 가능하다.

 

const person = {
  name: 'John',
  age: 30
};

person = { name: 'Alice', age: 25 }; // 불가능: 객체를 다른 객체로 재할당

하지만, 위 코드처럼 변수가 가리키는 객체 자체를 변경하는 것은 불가능하다.

이 코드를 실행하려 한다면, "Assignment to constant variable"  오류가 발생할 것이다.

 

다른 객체를 참조하도록 재할당하는 것은 불가능하지만, 객체의 속성을 변경하는 것이 가능한 이유는 무엇일까?

 

이는 const 키워드가 변수에 값을 재할당하지 못하도록 하는 불변성은 보장하지만,

객체 자체가 불변하도록은 보장하지 않기 때문이다.


그렇다면, const로 선언된 객체의 속성까지 불변하도록 선언하는 방법은 무엇일까?

 

기본 제공 메서드인 Object.freeze()를 사용해 객체의 속성까지 변경할 수 없게 처리할 수 있다.

freeze라는 단어에 맞게 "객체를 동결하기 위한 메서드"라고 표현하는데,

const obj = {
  prop: 123
};

Object.freeze(obj);

obj.prop = 456; // 이 코드는 무시됨
console.log(obj.prop); // 출력: 123

이런 식으로, freeze 된 객체를 수정하려는 코드는 실행 단계에서 무시하기 때문에 의도하지 않은 수정을 방지할 수 있다.

 

하지만, Object.freeze()는 선언된 객체 하나에만 적용되기 때문에, 중첩되어 선언된 객체 속성 변경까지는 보호할 수 없는데, 이를 얕은 동결(shallow freezing)이라 한다.

const obj = {
  prop: 123,
  nestedObj: { nestedProp: 456 }
};

Object.freeze(obj);

obj.prop = 789; // 이 코드는 무시
obj.nestedObj.nestedProp = 789; // 이 코드는 정상 실행됨

console.log(obj.prop); // 출력: 123
console.log(obj.nestedObj.nestedProp); // 출력: 789

 

중첩된 객체까지 동결 처리하려면?

중첩되어 있는 객체까지 모두 Object.freeze()를 통해 동결해야 한다.

const obj = {
  prop: 123,
  nestedObj: { nestedProp: 456 }
};

Object.freeze(obj);

Object.freeze(obj.nestedObj);

obj.prop = 789; // 이 코드는 무시
obj.nestedObj.nestedProp = 789; // 이 코드도 무시

console.log(obj.prop); // 출력: 123
console.log(obj.nestedObj.nestedProp); // 출력: 456