본문 바로가기

2주차

객체를 얼려주세요. Object.freeze()

안녕하세요 웹파트YB 강민하 입니다 ! !

 

자바스크립트의 객체는 매우 미끌미끌 유연하기 때문에 필요에 따라 잘 얼려주는게 중요하답니다.


 

JS의 객체는 기본적으로 변경 가능한(mutable) 데이터 구조이다. 즉, 객체의 속성에 대한 추가, 수정, 삭제가 자유롭다는 것을 의미한다.

 

하지만, 필요에 따라 객체를 불변(immutable)으로 만들어야 할 때가 있다.

예를 들면, 설정 관련 데이터라던가 사용자에게 보내는 메세지 ... 등등 데이터의 무결성을 보장해야할 때 객체를 불변으로 만들어야 한다.

 

var,let 말고 const 쓰면 해결되는거 아닌가요 ?

 

우선 const로 선언된 변수는 재할당이 불가능 하다.

하지만 객체와 배열같은 참조형 데이터에서는 값이 훅훅 변할 수 있다.

const number = 42;

number = 50; // 오류 발생: Assignment to constant variable.

 

원시 데이터 타입(number, string, boolean, ...)을 const로 선언하면 다른 값을 재할당할 수 없다.

 

const person = {
  name: "Minha",
  age: 25
};

person.age = 21; // 수정 가능
console.log(person.age); // 21

person.city = "Seoul"; // 추가 가능
console.log(person.city) // 'Seoul'

 

하지만 객체를 const로 선언할 경우, 객체의 속성을 변경할 수 있다. 즉 const불변성을 제공하지는 않는다.

 

그러면 불변성은 어떻게 보장하죠 ?

❄️ Object.freeze()

Object.freeze()메서드를 사용하면 객체의 속성을 추가, 삭제, 수정할 수 없게 만든다.

const person = {
  name: "Minha",
  age: 25
};

Object.freeze(person);

person.age = 26; // 수정 불가
console.log(person.age); // 25

person.city = "Seoul"; // 추가 불가
console.log(person.city); // undefined

 

위와 같이 Object.freeze()메서드는 객체를 동결하여 해당 객체의 속성을 변경할 수 없도록 한다.

 

❄️ Object.seal()

Object.seal()메서드도 불변성을 다루는 메서드이다.


편지지에서 봉인의 표시로 붙이는 종이라는 뜻인 seal 처럼 해당 메서드는 객체를 봉인해 새로운 속성을 추가할 수 없게 한다.
하지만 Object.freeze()와는 달리 기존 속성의 수정이 가능하다 !

const person = {
  name: "Minha",
  age: 25
};

Object.freeze(person);

person.age = 21; // 수정 가능
console.log(person.age); // 21

person.city = "Seoul"; // 추가 불가
console.log(person.city); // undefined

 

하지만... 두 메서드가 완벽한 불변성을 제공하지는 않는다.
Object.seal()Object.freeze() 모두 얕은 동결만 수행하기 때문에 중첩된 객체의 속성에 대해서는 변경이 가능하다.

 

const person = {
  name: "Minha",
  age: 25,
  address: {
    city: "Seoul",
    country: "Korea"
  }
};

// 객체를 동결
Object.freeze(person);

// 중첩된 객체의 속성 수정 시도
person.address.city = "Busan"; // 수정 가능
console.log(person.address.city); // "Busan"

 

 

address안에 중첩된 city 속성은 동결이 되지 않았고, 수정이 가능한걸 볼 수 있다.

 

❄️ 완전한 불변, deepFreeze

중첩된 객체까지 모두 동결해야하는 상황이라면 deepFreeze(깊은 동결)을 구현해야 한다.

function deepFreeze(object) {
  const propNames = Object.getOwnPropertyNames(object);

  for (let name of propNames) {
    const value = object[name];
    if (value && typeof value === "object") {
      deepFreeze(value);
    }
  }

  return Object.freeze(object);
}

// 사용 예
const person = {
  name: "Minha",
  address: {
    city: "Seoul",
    country: "Korea"
  }
};

deepFreeze(person);

person.address.city = "Busan"; // 무시됨
console.log(person.address.city); // "Seoul"

 

deepFreeze()함수를 사용하면 중첩된 객체까지 모두 동결되는걸 확인할 수 있다 !

 

중첩된 객체를 동결해야 한다면 deepFreeze 사용을 고려해보고,

외에는 Object.freeze()Object.seal()을 상황에 맞게 잘 사용한다면 객체의 불변성을 보장하며, 예기치 않은 오류를 방지할 수 있다 !