2 분 소요

Object.isExtensible 메서드: 확장이 가능한 객체인지 알아보는 메서드.

Object.isSealed 메서드: 밀봉된 객체인지 여부를 알아보는 메서드.

Object.isFrozen 메서드: 동결된 객체인지 여부를 알아보는 메서드.

| 구분 | 메서드 | 프로퍼티 추가 | 프로퍼티 삭제 | 프로퍼티 값 읽기 | 프로퍼티 값 쓰기 | 프로퍼티 어트리뷰트 재정의 | | :—: | :—: | :—: | :—: | :—: | :—: | :—: | | 객체 확장 금지 | Object.preventExtensions | X | O | O | O | O | | 객체 밀봉 | Object.seal | X | X | O | O | X | | 객체 동결 | Object.freeze | X | X | O | X | X |




객체 확장 금지

프로퍼티 추가만 금지

const person = { name: "Lee" };

console.log(Object.isExtensible(person)); //true

Object.preventExtensions(person);

console.log(Object.isExtensible(person)); //false

person.age = 20; //확장이 금지된 객체이므로 무시
//stric mode 에서는 에러.
console.log(person); // { name: 'Lee' }

delete person.name; //삭제는 가능

console.log(person); // {}

//정의에 의한 추가도 불가.
Object.defineProperty(person, "age", { value: 20 });
//TypeError: Cannot define property age, object is not extensible




객체 밀봉

밀봉된 객체는 읽기와 쓰기만 가능.

const person = { name: "Lee" };

console.log(Object.isSealed(person)); //false

Object.seal(person);

console.log(Object.isSealed(person)); //true

console.log(Object.getOwnPropertyDescriptors(person));
/*
{
  name: {
    value: 'Lee',
    writable: true,
    enumerable: true,
    configurable: false   //밀봉된 객체는 configurable이 false다.
  }
}
 */

//프로퍼티 추가가 금지된다.
person.age = 20; //무시, strict mode에서 에러
console.log(person); // { name:"Lee" }

//프로퍼티 삭제가 금지된다.
delete person.name; //무시 ,strict mode 에서는 에러.
console.log(person); // { name:"Lee" }

//프로퍼티 값 갱신은 가능하다.
person.name = "Kim";
console.log(person); //{ name: 'Kim' }

// 프로퍼티 어트리뷰트 재정의가 금지된다.
Object.defineProperty(person, "name", { configurable: true });
//TypeError: Cannot redefine property: name




객체 동결

동결된 객체는 읽기만 가능하다.

const person = { name: "Lee" };

console.log(Object.isFrozen(person)); //false

Object.freeze(person);

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

console.log(Object.getOwnPropertyDescriptors(person));
/*
{
  name: {
    value: 'Lee',
    writable: false,      //writeable 이 fasle다.
    enumerable: true,
    configurable: false   //configurable 이 fasle다.
  }
}
*/

//프로퍼티 추가가 금지된다.
person.age = 20; //무시, strict mode 에서는 에러.
console.log(person); //{ name: 'Lee' }

//프로퍼티 삭제가 금지된다.
delete person.name; //무시, strict mode 에서는 에러.
console.log(person); //{ name: 'Lee' }

//프로퍼티 값 갱신이 금지된다.
person.name = "Kim"; //무시, strict mode 에서는 에러.
console.log(person); //{ name: 'Lee' }

//프로퍼티 어트리뷰트 재정의가 금지된다.
Object.defineProperty(person, "name", { configurable: true });
//TypeError: Cannot redefine property: name




불변 객체

변경 방지 메서드들은 얕은 변경 방지로 직속 프로퍼티만 변경이 방지되고 중첩 객체까지는 영향을 주지는 못한다.

const person = {
  name: "Lee",
  address: { city: "Seoul" },
};

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

//직속 프로퍼티만 동결된다.
console.log(Object.isFrozen(person)); //true
//중첩 객체까지는 동결 안됨.
console.log(Object.isFrozen(person.address)); //false

person.address.city = "Busan";
console.log(person); //{ name: 'Lee', address: { city: 'Busan' } }

객체의 중첩 객체까지 동결하여 변경이 불가능한 읽기 전용의 불변 객체를 구현하려면 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드를 호출해야 한다.

function deepFreeze(target) {
  //객체가 아니거나 동결된 객체는 무시하고 객체이고 동결되지 않은 객체만 동결한다.
  if (target && typeof target === "object" && !Object.isFrozen(target)) {
    Object.freeze(target);

    Object.keys(target).forEach((key) => deepFreeze(target[key]));
  }
  return target;
}

const person = {
  name: "Lee",
  address: { city: "Seoul" },
};

//깊은 객체 동결
deepFreeze(person);

console.log(Object.isFrozen(person)); //true
//중첩객체까지 동결
console.log(Object.isFrozen(person.address)); //true

person.address.city = "Busan";
console.log(person); //{ name: 'Lee', address: { city: 'Seoul' } }

댓글남기기