다진 Javascript (8)

Kyle·2022년 6월 14일
0

Javascript

목록 보기
8/11
post-thumbnail

✔모던 자바스크립트 11장

참고 - https://poiemaweb.com/

객체 변경불가성

immutable value vs. mutable value

  • Javascript의 원시타입은 변경 불가능한 값 ex) boolean, null, undefined, number, string, symbol
var str = 'Hello';
str = 'world';

‘Hello’ 메모리 주소를 가리키고 있던 식별자 str은 새로운 문자열인 ‘world’를 메모리에 생성하고 이걸 가리키도록 변경된다. 따라서 두 문자열 모두 메모리에 존재하고 있다.

  • 원시 타입 이외의 모든 값은 객체(Object) 타입으로 변경 가능한 값

불변 데이터 패턴 (immutable data pattern)

  • 의도하지 않는 객체 변경 발생 원인: 레퍼런스를 참조한 다른 객체에서 객체를 변경
  • 해결 방법: 객체의 방어적 복사(Object.assign), 불변객체화를 통한 객체 변경 방지(Object.freeze)

Object.assign

  • 객체 변경이 필요한 경우 참조가 아닌 객체의 방어적 복사(defensive copy)를 통해 새로운 객체를 생성하여 변경한다. 이때의 복사는 deep copy가 아닌 shallow copy이다.
  • 타켓 객체로 소스 객체의 프로퍼티를 복사
// Syntax
Object.assign(target, ... sources)
  • 소스 객체의 프로퍼티와 동일한 프로퍼티를 가진 타켓 객체의 프로퍼티들은 소스 객체의 프로퍼티로 덮어쓰기 되고, 리턴값으로 타켓 객체를 반환한다.
// Copy
const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
console.log(obj == copy); // false
  • 타켓 객체가 빈 객체 리터럴이 아니라 이미 존재하는 객체일 경우, 타켓 객체와 소스 객체를 모두 병합한 결과로 타켓 객체가 변경된다.
// Merge
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const merge1 = Object.assign(o1, o2, o3);

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

Object.freeze

  • 객체를 불변 객체로 만들어서 프로퍼티의 변경을 방지
  • 그러나 객체 내부의 객체는 변경 가능
const user1 = {
  name: 'Lee',
  address: {
    city: 'Seoul'
  }
};

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' } }

user1.address.city = 'Busan'; // 변경 가능
console.log(user1); // { name: 'Lee', address: { city: 'Busan' } }
  • 내부 객체까지 변경 불가능하게 할 경우, 아래의 deep freeze 이용
function deepFreeze(obj) {
  const props = Object.getOwnPropertyNames(obj);

  props.forEach((name) => {
    const prop = obj[name];
    if(typeof prop === 'object' && prop !== null) {
      deepFreeze(prop);
    }
  });
  return Object.freeze(obj);
}

Immutable.js

  • Object.assign과 Object.freeze는 번거롭고 성능상 이슈가 있어서 큰 객체에서는 사용하지 않는 것이 좋고, 또 다른 대안으로 Immutable.js를 사용하는 방법도 있다.
  • Immutable.js를 설치해서 제공되는 영구 불변 데이터 구조를 사용하면 된다.
$ npm install immutable
profile
불편함을 고민하는 프론트엔드 개발자, 박민철입니다.

0개의 댓글