nhyunzi
[모던 자바스크립트 Deep Dive] 16 프로퍼티 어트리뷰트 본문
16.5 객체 변경 방지
자바스크립트는 객체의 변경을 방지하는 다양한 메서드를 제공한다.각 메서드들은 변경을 금지하는 강도가 다르다.
객체 확장 금지
Object.preventExtensions는 객체의 추가를 금지한다. 동적 추가와 Object.defineProperty 모두 금지한다. 확장여부는 Object.isExtensible()을 통해 알 수 있다.
const person = { name : 'Ahn'};
console.log(Object.isExtensible(person)); //true
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); //false
person.name = 'Kim'
console.log(person); // { name: 'Kim' }
delete person.name;
console.log(person); //{}
console.log(Object.getOwnPropertyDescriptor(person,'name'))
//{ value: 'Kim', writable: true, enumerable: true, configurable: true }
객체 밀봉
Object.seal은 프로퍼티 추가, 삭제, 재정의를 금지한다.
밀봉된 객체인지 여부는 Object.isSealed()로 확인 가능하다.
const person = { name : 'Ahn'};
console.log(Object.isSealed(person)); //false
Object.seal(person);
console.log(Object.isSealed(person)); //true
person.name = 'Kim'
console.log(person); // { name: 'Kim' }
console.log(Object.getOwnPropertyDescriptor(person,'name'))
//{ value: 'Kim', writable: true, enumerable: true, configurable: false }
객체 동결
Object.freeze는 객체를 동결해 추가, 삭제, 재정의 금지, 값 갱신을 금지한다. Object.isFrozen() 메서드로 확인 가능하다
const person = { name : 'Ahn'};
console.log(Object.isFrozen(person)); //false
Object.freeze(person);
console.log(Object.isFrozen(person)); //true
console.log(Object.getOwnPropertyDescriptor(person,'name'))
//{value: 'Ahn', writable: false, enumerable: true, configurable: false}
불변 객체
변경이 불가능한 읽기 전용의 객체이다.
앞에서 본 메서드들은 얕은 변경 방지로 직속 프로퍼티만 변경이 방지되고 중첩 객체까지는 영향을 주지는 못해서
만약 Object.freeze로 객체를 동결해도 중첩 객체까지는 동결이 불가능하다.
const person = {
name : 'Ahn',
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: 'Ahn', 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 : 'Ahn',
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: 'Ahn', address: { city: 'Seoul' } }