-
모던 자바스크립트 Deep Dive - 프로퍼티 어트리뷰트JavaScript 2021. 9. 16. 19:02
keyword = [ 내부 슬롯 , 내부 메서드 , 데이터 프로퍼티 , 접근자 프로퍼티 ]
내부 슬롯과 내부 메서드는 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드 이다.
내부 슬롯과 내부 메서드는 자바스크립트 엔진에서 실제로 동작하지만개발자가 직접 접근할 수 있도록 외부로 공개된 객체의 프로퍼티는 아니다. 따라서, 자바스크립트 엔진의 내부 로직이므로 직접 접근할 수 없다.하지만, 일부 내부 슬롯과 내부 메서드는 접근 수단을 제공 한다.
예를 들어, 모든 객체는 [[prototype]]이라는 내부 슬롯을 갖는다. 하지만 접근 할 수 없으며, __proto__로 접근할 수 있다.
const o = {}; o.[[prototype]] // Syntax Error o.__proto__ // Object.prototype
자바스크립트 엔진은 프로퍼티를 생성할때 프로퍼티 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의 한다.
프로퍼티 상태 : [값, 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부]
[[Value]] , [[Writable]] , [[Enumerable]] , [[Configurable]] 은 직접 접근 할 수 없다.
따라서, Object.getOwnPropertyDescriptor 메서드를 사용하여 간접적으로 확인할 수 있다.
cost person = { name : 'Kim' } console.log(Object.getOwnPropertyDescriptor(person,'name')); // { value : 'Kim', writable : true , enumerable : true , configurable : true }
Object.getOwnPropertyDescriptor는 하나의 프로퍼티에 대한 프로퍼티 디스크립터 객체를 반환하지만,
ES8 이후 Object.getOwnPropertyDescriptors 메서드는 모든 프로퍼티의 프로퍼티 어트리뷰트정보를 제공하는 프로퍼티 디스크립터 객체들을 반환한다.
const o = { name : 'Kim', age : 25, } console.log(Object.getOwnPropertyDescriptor(o,'name'); // { value : 'Kim', writable : true , enumerable : true , configurable : true } console.log(Object.getOwnPropertyDescriptors(o); // { // name : { value : 'Kim' , writable : true , enumerable : true , configurable : true }, // age : { value : 25 , writable : true , enumerable : true , configurable : true } // }
데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티
접근자 프로퍼티 : 데이터프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
데이터 프로퍼티
ex) prototype => 데이터 프로퍼티
[[Value]]
- 프로퍼티 키를 통해 접근하면 반환되는 값
- 프로퍼티 키를 통해 값을 변경하면 [[Value]]에 값을 재할당 하는 것
[[Writable]]
- 프로퍼티 값의 변경 가능 여부
- [[Writable]] 의 값이 false라면 읽기 전용 프로퍼티가 된다.
[[Enumerable]]
- 프로퍼티 열거 가능 여부
- [[Enumerable]] 의 값이 false라면 for ... in 문이나 Object.keys 메서드로 열거할 수 없다.
[[Configurable]]
- 프로퍼티 재정의 가능 여부
- [[Configurable]] 의 값이 false라면 해당 프로퍼티의 삭제 , 변경이 금지된다.
접근자 프로퍼티
접근자 프로퍼티는 자체적으로 값을 갖지 않는다.
다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티다.ex ) __proto__ => 접근자 프로퍼티
[[Get]]
접근자 프로퍼티 키로 접근하면 데이터 프로퍼티의 값을 읽어들이는 [[Get]] 의 값(getter 함수)가 호출되어 프로퍼티 값을 반환 받는다.
[[Set]]
접근자 프로퍼티 키로 접근하면 데이터 프로퍼티의 값을 저장하는 [[Set]] 의 값(setter 함수)가 호출되어 프로퍼티 값을 저장한다.
[[Enumerable]]
데이터 프로퍼티의 Enumerable과 같다.
[[Configurable]]
데이터 프로퍼티의 Configurable과 같다.
const person = { firstName : 'YoungJin', lastName : 'Kim' get fullName(){ return `${this.firstName} ${this.lastName}`; } set fullName(name){ [this.firstName, this.lastName] = name.split(' '); } }; // fullName에 접근하면 getter 함수 호출 console.log(person.fullName) // YoungJin Kim // fullName에 값을 저장하면 setter 함수 호출 person.fullName = 'Jenny Kim' console.log(person.fullname) // 'Jenny Kim' let descriptor = Object.getOwnPropertyDescriptor(person,'firstName'); console.log(descriptor); // { value : 'YoungJin' , writable : true , enumerable : true , configurable : true } descriptor = Object.getOwnpropertyDescriptor(person,'fullName'); console.log(descriptor); // { get : f, set : f, enumerable : true , configurable : true }
person의 firstName과 lastName은 데이터 프로퍼티이고
person의 fullName은 접근자 프로퍼티이다.
프로퍼티의 어트리뷰트 정의하기
Object.defineProperty(object,key,addtribute)
const person = {} Object.defineProperty(person,'firstName',{ value : 'YoungJin', writable : true, enumarable : true, configurable : true }); Object.defineProperty(person,'fullName',{ get() { return `${this.firstName} ${this.lastName}` }, set(name){ [ this.firstName , this.lastName ] = name.split(' '); }, enumerable : true, configurable : true }); Object.defineProperty(person,'lastName',{ value : 'Kim' }); let descriptor = Object.getOwnPropertyDescriptor(person,'lastName'); console.log(descriptor); // { value : 'Kim', writable : false, enumerable : false , configurable : false } console.log(Object.keys(person)); // ["firstName"] person.lastName = 'Lee' // X delete person.lastName // X
객체 변경 금지
구분 메서드 프로퍼티 추가 프로퍼티 삭제 프로퍼티 값 읽기 프로퍼티 값 쓰기 프로퍼티 어트리뷰트 재정의 객체 확장 금지 Object.preventExtensions X O O O O 객체 밀봉 Object.seal X X O O X 객체 동결 Object.freeze X X O X X 'JavaScript' 카테고리의 다른 글
모던 자바스크립트 Deep Dive - 함수와 일급 객체 (0) 2021.09.16 모던 자바스크립트 Deep Dive - 생성자 함수에 의한 객체 생성 (0) 2021.09.16 모던 자바스크립트 Deep Dive - let, const 키워드와 블록 레벨 스코프 (0) 2021.09.16 모던 자바스크립트 Deep Dive - 전역 변수의 문제점 (0) 2021.09.16 모던 자바스크립트 Deep Dive - 스코프 (0) 2021.09.16