Chapter 16 프로퍼티 어트리뷰트
in Frontend / Js / Javascript
property attributes
16.1 내부 슬롯과 내부 메서드
- 명세에 따른 JS 엔진 내부 로직
- 내부 슬롯 (Internal Slot), 내부 메서드 (Internal Method) :
[[...]]
표기법으로 표현 - 개발자가 직접 접근은 불가능
- 객체의
[[Prototype]]
내부 슬롯의 경우__proto__
접근자 프로퍼티를 통해 간접적으로 접근 가능
- 객체의
16.2 Property Attribute & Property Descriptor Object
프로퍼티 어트리뷰트 (Property Attribute) : 객체의 property 생성될때 자동으로 정의됨
[[Value]]
,[[Writable]]
,[[Enumerable]]
,[[Configurable]]
- 프로퍼티 어트리뷰트에 직접 접근하려면
Object.getOwnPropertyDescriptor/s
메서드 사용
const person = { name: "Lee", }; person.age = 20; // 한개 console.log(Object.getOwnPropertyDescriptor(person, "name")); // { value: 'Lee', writable: true, enumerable: true, configurable: true } // 전부 console.log(Object.getOwnPropertyDescriptors(person)); // { // name: { value: 'Lee', writable: true, enumerable: true, configurable: true }, // age: { value: 20, writable: true, enumerable: true, configurable: true } // }
16.3 데이터 프로퍼티와 접근자 프로퍼티
데이터 프로퍼티, 접근자 프로퍼티 구분
- 데이터 프로퍼티 (Data Property) :
[[Value]]
,[[Writable]]
,[[Enumerable]]
,[[Configurable]]
접근자 프로퍼티 (Accessor Property) :
[[Get]]
,[[Set]]
,[[Enumerable]]
,[[Configurable]]
const person = { name: "Gildong", surname: "Hong", get fullName() { // GETTER return `${this.name} ${this.surname}`; }, set fullName(value) { // SETTER, 값 할당 [this.name, this.surname] = value.split(" "); }, }; console.log(person.fullName); // <-- fullName GETTER 로 동작 person.fullName = "DongGil Hong"; // <-- SETTER 로 동작
- 데이터 프로퍼티 (Data Property) :
person.fullName
로직 따라가기- (isValidKey?)
fulName
은 유효한 키인가? - (isExist?)
person
객체에fullName
프로퍼티가 존재하는가? - (isData/AccessorProperty?)
fullName
은 데이터 or 접근자 프로퍼티 중 어떤 것인가? - (isGetter/isSetter?)
fullName
은 getter인가? ->[[Get]]
- (isValidKey?)
16.4 프로퍼티 정의
const person = {};
Object.defineProperty/Object.defineProperties
메서드로 프로퍼티 custom 정의가능함Object.defineProperty(person, "name", { value: "Gildong", writable: true, enumerable: true, configurable: true, });
이렇게 다른 항목들은 생략하면 기본 value: undefined, boolean 값들 (writable, enumerable, configurable)은 false로 들어감!
Object.defineProperty(person, "age", { value: 20, });
enumerable: false
-> for…in 같은 순회 대상에서 제외writable: false
-> 값 재할당, delete 무시됨 (error X)configurable: false
-> 재정의 (defineProperty) 불가능
동시에 여러개 정의 가능
Object.defineProperties(person, { name: { value: "Gildong" }, age: { value: 20 }, });
16.5 객체 변경 방지
Object.preventExtensions
: 프로퍼티 추가 금지 (isExtensible
메서드로 확인)- 1) 동적 추가,
- 2) object.defineProperty로도 추가 재정의 불가능
- 삭제 가능
Object.seal
: 프로퍼티 추가, 삭제 금지, 재정의 가능 (isSealed
메서드로 확인)Object.freeze
: readonly. (isFrozen
메서드로 확인)- 불변 객체 원할 시: 전부 shallow 작업들이라, 중첩 객체까지 보호하려면 재귀적으로 돌아야함