기존 블로그에 작성한 내용을 velog로 이전한 글입니다
프로퍼티 어트리뷰트:
프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능여부
프로퍼티 디스크립터:
프로퍼티 어트리뷰트 정보를 담고 있는 객체
getOwnPropertyDescriptor
로 간접적인 확인 가능
데이터 프로퍼티:
키와 값으로 구성된 프로퍼티
어트리뷰트: [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
접근자 프로퍼티:
다른 데이터 프로퍼티 값을 읽거나 저장할 때 호출되는 접근자 프로퍼티들
어트리뷰트: [[Get]], [[Set]], [[Enumerable]], [[Configurable]]
Get 메소드가 호출될 때:
프로퍼티 키 유효성 확인 -> 프로토타입 체인에서 프로퍼티 검색 ->
프로퍼티 종류 확인 -> getter 함수를 호출하여 그 결과 반환
// 일반 객체의 __proto__는 접근자 프로퍼티이다.
Object.getOwnPropertyDescriptor(Object.prototype, '__proto__');
// {get: ƒ, set: ƒ, enumerable: false, configurable: true}
// 함수 객체의 prototype은 데이터 프로퍼티이다.
Object.getOwnPropertyDescriptor(function() {}, 'prototype');
{value: {…}, writable: true, enumerable: false, configurable: false}
새로운 프로퍼티 추가와 함께 어트리뷰트를 정의하거나 기존 프로퍼티 어트리뷰트를 재정의 하는 것
Object.defineProperty로 프로퍼티의 어트리뷰트를 정의할 수 있다.
// 데이터 프로퍼티 정의
const person = {};
Object.defineProperty(person, 'firstName', {
value: 'Ungmo',
writable: true,
enumerable: true,
configurable: true
});
프로퍼티 디스크립터 객체의 프로퍼티를 일부 생략시 기본값은 다음과 같다.
프로퍼티 디스크립터 객체의 프로퍼티 | 대응하는 프로퍼티 어트리뷰트 | 디스크립터 객체의 프로퍼티 누락 시의 기본값 |
---|---|---|
value | [[Value]] | undefined |
get | [[Get]] | undefined |
set | [[Set]] | undefined |
writable | [[Writable]] | false |
enumerable | [[Enumerable]] | false |
configurable | [[Configurable]] | false |
얕은 변경 방지 방법
구분 | 메소드 | 추가 | 삭제 | 값 읽기 | 값 쓰기 | 재정의 |
---|---|---|---|---|---|---|
객체 확장 금지 | Object.preventExtensions | ✕ | O | O | O | O |
객체 밀봉 | Object.seal | ✕ | ✕ | O | O | ✕ |
객체 동결 | Object.freeze | ✕ | ✕ | O | ✕ | ✕ |
깊은 변경 방지 방법
재귀 함수를 이용하여 중첩 객체까지 동결해야 한다.
function deepFreeze(target) {
// 객체가 아니거나 동결된 객체는 무시하고 객체이고 동결되지 않은 객체만 동결한다.
if (target && typeof target === 'object' && !Object.isFrozen(target)) {
Object.freeze(target);
Object.keys(target).forEach(key => deepFreeze(target[key]));
}
return target;
}