개발 기술/사소하지만 놓치기 쉬운 개발 지식

[JS] Object.freeze, Object.seal의 차이

by GicoMomg (Lux) 2022. 4. 9.

🙂 이번시간에는 객체의 변경을 막는 Object.freeze, Object.seal의 차이점에 대해 알아보았다.


0. 왜 두 함수가 필요할까?

  • 우리는 let, var, const를 사용해 변수를 선언할 수 있다.
  • 그리고 그 중 const로 선언된 변수는 값을 재할당할 수 없다.
const name = "susan";

name = "lala";  // TypeError: Assignment to constant variable.


🤔 그렇다면 const로 선언된 객체도 값의 재할당이 불가할까? 답은 아니다.

  • 객체에 데이터를 할당하면, 데이터 자체를 저장하는 게 아닌 데이터를 저장한 메모리의 주소값을 참조한다.
  • 결국 객체가 참조하는 주소가 변하지 않는 한, const로 선언해도 값을 변경할 수 있다.
const obj = {'a': 12, 'b': 13};
obj.a = 55;

console.log(obj);  // {'a': 55, 'b': 13}
  • 그럼 객체의 재할당은 막을 수 없나? 아니다! Object.freeze, Object.seal을 사용하면 된다.



1. Object.freeze?

  • 객체의 변경을 막는 함수이다.
  • Object.freeze() 처리를 한 객체는 속성 추가, 속성 제거는 물론 속성값 변경 또한 불가하다.
const obj = {'a': 12, 'b': 13};

Object.freeze(obj);
obj.a = 44;          // {'a': 12, 'b': 13}  - 변경 ❌
obj.c = 11;          // {'a': 12, 'b': 13}  - 추가 ❌
delete obj.a;        // {'a': 12, 'b': 13}  - 삭제 ❌

  • 단, Object.freeze() 처리를 한 객체라도, 내부 객체의 값은 변경할 수 있다. (얕은 freeze)
const obj = {'a': {}};

Object.freeze(obj);
obj.a.b = 12;       // {'a': {b: 12}}  - 변경 ⭕
obj.a.b = 55;       // {'a': {b: 55}}  - 추가 ⭕
delete obj.a.b;     // {'a': {}}       - 삭제 ⭕
  • 만약 내부 객체의 변화도 막고 싶다면, 이 문서에서 deepFreeze함수를 참고하자



2. Object.seal?

  • Object.freeze와 유사하게 객체의 변경을 막는 역할을 한다.
  • 단, Object.seal() 처리를 한 객체는 속성에 대한 변경만 불가하다.
const obj = {'a': 12, 'b': 13};

Object.freeze(obj);
obj.a = 44;          // {'a': 44, 'b': 13}  - 변경 ⭕
obj.c = 11;          // {'a': 44, 'b': 13}  - 추가 ❌
delete obj.a;        // {'a': 44, 'b': 13}  - 삭제 ❌  



3. 두 함수의 차이점

😃 Object.freeze, Object.seal에 대해 각각 알아봤으니 차이점도 알아보자

(1) 새 속성 추가가 가능한가?

  • Object.freeze, Object.seal 둘 다 불가능하다.
const obj = {'a': 1};

Object.freeze(obj);
obj.b = 12;          // {'a': 1} ❌
const obj = {'a': 1};

Object.seal(obj);
obj.b = 12;         // {'a': 1} ❌

  • 단 내부 객체의 속성 추가는 가능하다!
const obj = {'a': {}};

Object.freeze(obj);
obj.a.b = 12;         // {'a': {'b': 12}} ⭕
const obj = {'a': {}};

Object.seal(obj);
obj.a.b = 12;        // {'a': {'b': 12}} ⭕

(2) 속성 제거가 가능한가?

  • 둘 다 기존의 속성을 제거하는 행위는 불가하다. (단 내부 객체에서는 삭제 가능)
const obj = {'a': 1};

Object.freeze(obj);
delete obj.a;         // {'a': 1} ❌
const obj = {'a': 1};

Object.seal(obj);
delete obj.a;         // {'a': 1} ❌

(3) 기존 속성의 값을 바꿀 수 있는가?

  • Object.freeze는 불가하지만, Object.seal은 속성값 변경은 가능하다!
const obj = {'a': 1};

Object.freeze(obj);
obj.a = 12;          // {'a': 1} ❌   
const obj = {'a': 1};

Object.seal(obj);
obj.a = 12;         // {'a': 12} ⭕

결국, 두 함수의 핵심적인 차이점은 기존 속성의 값을 변경가능한지 여부이다.


반응형

댓글