불변 객체를 만드는 방법

김영진·2022년 7월 18일
0

TIL

목록 보기
8/29
post-thumbnail

의도하지 않은 객체의 변경이 발생하는 원인의 대다수는 "레퍼런스를 참조한 다른 객체에서 객체를 변경"하기 때문이다.

이 문제의 해결 방법은 객체를 불변 객체로 만들어 프로퍼티의 변경을 방지하며, 객체의 변경이 필요한 경우에는 참조가 아닌 객체의 방어적 복사를 통해 새로운 객체를 생성한 후 변경한다.


Object.assign (방어적 복사하기)

Object.assign은 타겟 객체로 소스 객체의 프로퍼티를 복사한다. 이때 소스 객체의 프로터이와 동일한 프로퍼티를 가진 타겟 객체의 프로터피들은 소스 객체의 프로퍼티로 덮어쓰기된다.

// Merge
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const merge1 = Object.assign(o1, o2, o3); //o1이 타겟이 된다.

console.log(merge1); // { a: 1, b: 2, c: 3 }
console.log(o1);     // { a: 1, b: 2, c: 3 }, 타겟 객체가 변경된다!

// Merge
const o4 = { a: 1 };
const o5 = { b: 2 };
const o6 = { c: 3 };

const merge2 = Object.assign({}, o4, o5, o6); //빈 객체가 타겟이 된다.

console.log(merge2); // { a: 1, b: 2, c: 3 }
console.log(o4);     // { a: 1 }

Object.assign을 사용하여 기존 객체를 변경하지 않고 객체를 복사하여 사용할 수 있다.


Object.freeze (불변 객체 만들기)

Object.freeze()를 사용하여 불변 객체로 만들 수 있다.

const user1 = {
  name: 'Lee',
  address: {
    city: 'Seoul'
  }
};

// Object.assign은 완전한 deep copy를 지원하지 않는다.
const user2 = Object.assign({}, user1, {name: 'Kim'});

console.log(user1.name); // Lee
console.log(user2.name); // Kim

Object.freeze(user1);

user1.name = 'Kim'; // 무시된다!

console.log(user1); // { name: 'Lee', address: { city: 'Seoul' } }

console.log(Object.isFrozen(user1)); // true

하지만 객체 내부의 객체는 변경 가능하다.

const user = {
  name: 'Lee',
  address: {
    city: 'Seoul'
  }
};

Object.freeze(user);

user.address.city = 'Busan'; // 변경된다!
console.log(user); // { name: 'Lee', address: { city: 'Busan' } }

Immutable.js

Object.assign과 Object.freeze를 사용하여 불변 객체를 만드는 방법은 번거로울 뿐더러 성능 이슈가 있어 큰 객체에서는 사용을 지양한다. 또 다른 대안으로 Facebook이 제공하는 Immutable.js를 사용하는 방법이 있다.


참고 사이트

https://poiemaweb.com/

profile
노션 및 티스토리로 이동 예정입니다.

0개의 댓글