**프로퍼티 어트리뷰트(Property Attribute)**는 ECMAScript 명세에서 객체 프로퍼티의 상태를 가리키기 위해 사용하는 용어이다.
프로퍼티 어트리뷰트는 내부 슬롯 중 객체 프로퍼티의 상태를 나타내는 내부 슬롯을 가리킨다.
데이터 프로퍼티가 가지는 어트리뷰트는 다음과 같다.
프로퍼티 어트리뷰트 | 기본값 | 설명 |
---|---|---|
[[Value]] |
undefined |
- ECMAScript 값을 값으로 가진다. - 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값이다. - 프로퍼티 키를 통해 프로퍼티 값을 바꾸면 [[Value]] 에 값을 재할당한다. 프로퍼티 키가 없다면 프로퍼티를 동적 생성하고 생성된 프로퍼티의 [[Value]] 에 값을 저장한다. |
[[Writable]] |
false |
- 프로퍼티의 값을 변경할 수 있는지 나타내는 boolean 값을 가진다.- false 이면 그 프로퍼티는 읽기 전용 프로퍼티가 된다. |
[[Enumerable]] |
false |
- 프로퍼티를 열거할 수 있는지 나타내는 boolean 값을 가진다.- false 이면 그 프로퍼티는 for... in 과 Object.keys 메서드 등으로 열거할 수 없다. |
[[Configurable]] |
false |
- 프로퍼티를 재정의할 수 있는지 나타내는 boolean 값을 가진다.- false 이면 그 프로퍼티를 삭제하거나 값을 변경할 수 없다. 단, [[Writable]] 이 true 라면 [[Value]] 를 변경하거나 [[Writable]] 을 false 로 바꿀 수 있다. |
프로퍼티가 생성될 때 [[Value]]
의 값은 프로퍼티의 값으로 초기화되며 나머지 프로퍼티 어트리뷰트는 true
로 초기화된다.
접근자 프로퍼티는 다음과 같은 프로퍼티 어트리뷰트를 갖는다.
프로퍼티 어트리뷰트 | 기본값 | 설명 |
---|---|---|
[[Get]] |
undefined |
데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수를 값으로 가진다. 이때 접근자 함수를 getter라고 한다. |
[[Set]] |
undefined |
데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수를 값으로 가진다. 이때 접근자 함수를 setter라고 한다. |
[[Enumerable]] |
false |
데이터 프로퍼티에서와 동일 |
[[Configurable]] |
false |
데이터 프로퍼티에서와 동일 |
const champion = {
firstName: 'Luxanna',
lastName: 'Crownguard',
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
};
console.log(champion.fullName); // Luxanna Crownguard
champion.fullName = 'Caitlyn Kiramman';
console.log(champion.fullName); // Caitlyn Kiramman
접근자 프로퍼티 getName
으로 프로퍼티의 값에 접근하면 내부적으로 [[Get]]
내부 메서드가 호출된다.
- 프로퍼티 키가 유효한지 확인한다. 프로퍼티 키
'fullName'
는 문자열이므로 유효하다. - 프로토타입 체인에서 프로퍼티를 검색한다.
champion
객체에fullName
프로퍼티가 존재한다. - 검색한 프로퍼티가 데이터 프로퍼티인지 접근자 프로퍼티인지 확인한다.
fullName
프로퍼티는 접근자 프로퍼티이다. - 접근자 프로퍼티라면 프로퍼티 어트리뷰트
[[Get]]
의 값인 getter 함수를 호출한다. 여기서는fullName
의 프로퍼티 어트리뷰트[[Get]]
의 값인 getter 함수를 호출한다. 이 getter 함수는[[Call]]
내부 메서드와 함께 호출된다.
JavaScript는 프로퍼티 어트리뷰트에 대한 프로퍼티 디스크립터 객체(PropertyDescriptor
)를 반환하는 메서드를 제공한다.
Object.getOwnPropertyDescriptor(obj, prop)
: 하나의 프로퍼티에 대한 프로퍼티 디스크립터 객체 반환Object.getOwnPropertyDescriptors(obj)
: 객체의 모든 프로퍼티에 대한 프로퍼티 디스크립트 객체를 반환
const champion = {
name: 'lux'
};
const descriptor = Object.getOwnPropertyDescriptors(champion, 'name');
console.log(JSON.stringfy(descriptor));
// {"name":{"value":"lux","writable":true,"enumerable":true,"configurable":true}}
Object - Object.getOwnPropertyDescriptor()
와 Object.getOwnPropertyDescriptors()
를 참고한다.
프로퍼티 정의는 프로퍼티 어트리뷰트를 명시하여 새로운 프로퍼티를 추가하거나 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것이다. JavaScript는 프로퍼티 정의를 할 수 있는 메서드를 제공한다.
Object.defineProperty()
: 하나의 프로퍼티 어트리뷰트를 정의하고 해당 객체를 반환Object.defienProperties()
: 여러 개의 프로퍼티 어트리뷰트를 정의하고 해당 객체를 반환
const champion = {};
Object.defineProperty(champion, 'name', {
value: 'luxanna',
writable: true,
enumerable: true,
configurable: true
});
console.log(champion.name); // laxanna
const descriptor = Object.getOwnPropertyDescriptors(champion, 'name');
console.log(JSON.stringfy(descriptor));
// {"name":{"value":"lux","writable":true,"enumerable":true,"configurable":true}}
Object - Object.defineProperty()
와 Object.defineProperties()
를 참고한다.