반응형
Object,즉 객체는 변경이 가능한 값이다. 프로퍼티를 삭제, 읽기, 갱신, 쓰기, 재정의 등을 할 수 있다. 자바스크립트에서는 이 객체의 가변성에 제한을 줄 수 있는 메소드들을 제공한다. 아래와 같이 세가지가 존재한다
구분 | 메소드 | 프로퍼티 추가 | 프로퍼티 삭제 | 프로퍼티 값 읽기 | 프로퍼티 값 쓰기 | 프로퍼티 어트리뷰트 재정의 |
객체 확장금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
객체 확장 금지
객체 확장 금지는 Object.preventExtensions메소드로 객체 확장을 금지한다. 객체 확장을 금지한다는 것은 프로퍼티 추가하는것이 제한된다는 것을 의미한다. 프로퍼티 동적 추가, Object.defineProperty()모두 포함이 된다. Object.isExtensibel()로 확장 가능한지 확인할 수 있다.
//객체 확장 방지
const person = {name : "Lee"};
//Object.isExtensible() : 객체가 확장 가능한지를 확인한다. bool타입을 반환한다.
console.log(Object.isExtensible(person)); // true
//Object.preventExtensions : 프로퍼티 추가를 금지한다. 프로퍼티 삭제, 값 읽기, 값 쓰기, 어트리뷰터 재정의는 가능하다
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); // false
person.age = 30; // 무시된다.
console.log(person); // age프로퍼티가 추가되지 않은것을 볼 수 있다.
객체 밀봉
객체 밀봉은 Object.seal메소드로 밀봉할 수 있다. 밀봉된 객체는 추가는 물론이고, 객체의 읽고 쓰기만 가능해지게 된다. Object.isSearled()를 사용해서 밀봉되었는지 확인할 수 있다.
// 객체 밀봉
const person2 = {name : "Yoon"};
// Object.isSealed() : 객체가 밀봉되었는지를 확인한다 마찬가지로 bool타입을 반환한다.
console.log(Object.isSealed(person2));
// 프로퍼티를 밀봉한다. 프로퍼티 추가, 프로퍼티 삭제, 프로퍼티 재정의를 금지한다.
Object.seal(person2)
console.log(Object.isSealed(person2));
console.log(Object.getOwnPropertyDescriptor(person2,'name')); // configurable(재정의 여부)가 false인것을 알 수 있다.
/* Cannot redefine propery "name"
Object.defineProperty(person2,'name',{
value : "Park",
writable : true,
enumerable : true,
configurable : true
});
*/
/*TypeError: Cannot define property age, object is not extensible
Object.defineProperty(person2, 'age',{
value : 20,
writable : true,
enumerable : true,
configurable : true
});
*/
/* Cannot redefine
Object.defineProperty(person2, 'name', {
configurable : true
})*/
console.log(person2)
객체 동결
객체 동결은 프로퍼티 추가 및 삭제, 프로퍼티 어트리뷰트 재정의, 값 쓰기 모두 제한되며 오로지 읽기만 가능한 상태이다. Object.freeze메소드로 동결을 할 수 있으며, Object.isFrozen()으로 동결되었는지 확인 가능하다
//객체 동결 : 프로퍼티 값 읽기만 가능하며, 프로퍼티 추가, 프로퍼티 삭제, 값쓰기, 프로퍼티 어트리뷰트 재정의 모두 불가능하다.
const person3 = {name : "Yoon"}
console.log(Object.isFrozen(person3));
Object.freeze(person3);
console.log(Object.isFrozen(person3));
console.log(Object.getOwnPropertyDescriptor(person3, 'name'))
person3.age = 30; //무시된다
console.log(person3);
/*
Object not extensible
Object.defineProperty(person3, 'age',{
value: 30,
writable : true,
configurable : true,
enumerable : true
})
*/
불변 객체
위 세가지 객체 밀봉, 객체 확장금지, 객체 동결은 모두 얕은 범위에 대해서만 적용한다. 이말은 즉슨 중첩 범위에 대해서는 적용하지 못한다는 것이다. 중첩범위까지 모두 동결 / 확장금지 / 밀봉을 하고 싶다면 재귀적으로 객체들에 대해서 변경 방지 작업을 해주면 된다.
function deepFrozen(target){
if(target && typeof target === "object" && !Object.isFrozen(target)){
Object.freeze(target);
Object.keys(target).forEach(key => deepFrozen(target[key]));
}
return target;
}
const person5 = {
name : "Lee",
address : {
city : "Seoul"
}
};
deepFrozen(person5);
console.log(Object.isFrozen(person5));
console.log(Object.isFrozen(person5.address));
person5.address.city = "Busan";
console.log(person5); // 변경되지 않음
console.log(Object.getOwnPropertyDescriptors(person5.address))
반응형
'Language > JavaScript' 카테고리의 다른 글
[javascript] 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체 (0) | 2021.12.14 |
---|---|
[javascript] var VS let (0) | 2021.12.14 |
[javascript]함수레벨 스코프 (0) | 2021.12.14 |