프로퍼티 플래그와 설명자
: 객체에는 프로퍼티가 저장 됨
: 프로퍼티는 키-값 쌍의 구조의 단순한 자료구조가 아닌 유연하고 강력한 자료구조 임
프로퍼티 플래그
: 객체 프로퍼티는 값과 플래그라는 특별한 속성 3가지를 가짐
- writable
: 값을 수정할 수 있는 여부
- enumerable
: 반복문을 사용해 나열 할수 있는 여부
- configurable
: 프로퍼티 삭제나 플래그 수정 가능 여부
=> 일반적인 방식으로 프로퍼티를 생성하면 해당 프로퍼티의 플래그는 모두 true가 되며 언제든지 수정 가능
Object.getOwnPropertyDescriptor
: 특정 프로퍼티에 대한 모든 정보를 얻을 수 있음
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
- obj
: 정보를 얻고자 하는 객체
- propertyName
: 정보를 얻고자 하는 객체 내 프로퍼티
Object.defineProperty
: 객체와 프로퍼티의 플래그를 변경
Object.defineProperty(obj, propertyName, descriptor)
- obj
: 설명자를 적용하고 싶은 객체
- propertyName
: 설명자를 적용하고 싶은 객체와 객체 프로퍼티
- descriptor
: 적용하고자 하는 프로퍼티 설명자
=> 해당 객체의 프로퍼티가 없는 경우 새로운 프로퍼티를 만듬
=> 이때 플래그 값은 false
=> descriptor에 true를 명시해야함
Writable 플래그
let user = {
name: "John"
};
Object.defineProperty(user, "name", {
writable: false
});
user.name = "Pete"; // Error: Cannot assign to read only property 'name'
※ defineProperty를 이용하여 밑바닥 부터 만들기
let user = { };
Object.defineProperty(user, "name", {
value: "John",
// defineProperty를 사용해 새로운 프로퍼티를 만들 땐, 어떤 플래그를 true로 할지 명시해주어야 합니다.
enumerable: true,
configurable: true
});
alert(user.name); // John
user.name = "Pete"; // Error
enumerable 플래그
let user = {
name: "John",
toString() {
return this.name;
}
};
Object.defineProperty(user, "toString", {
enumerable: false
});
// 이제 for...in을 사용해 toString을 열거할 수 없게 되었습니다.
for (let key in user) alert(key); // name
configurable 플래그
let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');
alert( JSON.stringify(descriptor, null, 2 ) );
/*
{
"value": 3.141592653589793,
"writable": false,
"enumerable": false,
"configurable": false
}
*/
Math.PI = 3; // Error
// 수정도 불가능하지만 지우는 것 역시 불가능합니다.
영원히 변경할 수 없는 프로퍼티 만들기
let user = { };
Object.defineProperty(user, "name", {
value: "John",
writable: false,
configurable: false
});
// user.name 프로퍼티의 값이나 플래그를 변경할 수 없습니다.
// 아래와 같이 변경하려고 하면 에러가 발생합니다.
// user.name = "Pete"
// delete user.name
// Object.defineProperty(user, "name", { value: "Pete" })
Object.defineProperty(user, "name", {writable: true}); // Error
Object.defineProperties
: 프로퍼티 여러 개를 한 번에 정의
Object.defineProperties(obj, {
prop1: descriptor1,
prop2: descriptor2
// ...
});
Object.defineProperties(user, {
name: { value: "John", writable: false },
surname: { value: "Smith", writable: false },
// ...
});
Object.getOwnPropertyDescriptors
: 프로퍼티 설명자를 한꺼번에 가져옴
: 이를 이용하여 객체 복사 시 플래그도 같이 가져올 수 있음
let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
객체 수정을 막아주는 다양한 메서드
- Object.preventExtensions(obj)
: 객체에 새로운 프로퍼티를 추가할 수 없게 함
- Object.seal(obj)
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제를 막아줌
: 프로퍼티 전체에 configurable: false를 설정하는 것과 동일한 효과
- Object.freeze(obj)
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제, 수정을 막아줌
: 프로퍼티 전체에 configurable: false, writable: false를 설정하는 것과 동일한 효과
※ 위 세 가지 메서드를 사용해서 설정한 제약사항을 확인할 때 사용할 수 있는 메서드
- Object.isExtensible(obj)
: 새로운 프로퍼티를 추가하는 게 불가능한 경우 false를, 그렇지 않은 경우 true를 반환
- Object.isSealed(obj)
: 프로퍼티 추가, 삭제가 불가능하고 모든 프로퍼티가 configurable: false이면 true를 반환
- Object.isFrozen(obj)
: 프로퍼티 추가, 삭제, 변경이 불가능하고 모든 프로퍼티가 configurable: false, writable: false이면 true를 반환
Refference
'Programming > JavaScript' 카테고리의 다른 글
모던 자바스크립트 (프로토타입과 프로토타입 상속) 6-1. 프로토타입 상속 / 함수의 prototype 프로퍼티 (0) | 2022.04.23 |
---|---|
모던 자바스크립트 (객체 프로퍼티 설정) 5-2. 프로퍼티 getter와 setter (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-6. 함수 바인딩 (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-5. call/apply와 데코레이터, 포워딩 (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-4. setTiemout과 setInterval을 이용한 호출 스케줄링 (0) | 2022.04.23 |