Web/JavaScript
[JavaScript] 모던 자바스크립트 Deep Dive 16장 - 프로퍼티 어트리뷰트
어징베
2022. 7. 25. 23:40

16.1 내부 슬롯과 내부 메서드
내부 슬롯과 내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드이다.
16.2 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
프로퍼티 상태: 프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부
프로퍼티 어트리뷰트: 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯 [[value]], [[Writable]], [[Enumerable]], [[Configurable]]
const person = {
name: 'Eo'
};
// 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다.
// 첫 번째 매개변수에는 객체의 참조를 전달하고, 두 번째 매개변수에는 프로퍼티 키를 문자열로 전달
console.log(Object.getOwnPropertyDescriptor(person, 'name'));
// { value: 'Eo', writable: true, enumerable: true, configurable: true }
16.3 데이터 프로퍼티와 접근자 프로퍼티
- 데이터 프로퍼티: 키와 값으로 구성된 일반적인 프로퍼티
- 접근자 프로퍼티: 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
16.3.1 데이터 프로퍼티
| 프로퍼티 어트리뷰트 |
프로퍼티 디스크립터 객체의 프로퍼티 |
설명 |
| [[Value]] | value | - 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값이다. - 프로퍼티 키를 통해 프로퍼티 값을 변경하면 [[value]]의 값을 재할당한다. 이때 프로퍼티가 없으면 프로퍼티를 동적 생성하고 생성된 프로퍼티의 [[Value]]에 값을 저장한다. |
| [[Writable]] | writable | - 프로퍼티 값의 변경 가능 여부를 나타내며 불리언 값을 갖는다. - [[Writable]]의 값이 false인 경우 해당 프로퍼티의 [[Value]]의 값을 변경할 수 없는 읽기 전용 프로퍼티가 된다. |
| [[Enumerable]] | enumerable | - 프로퍼티의 열거 가능 여부를 나태내며 불리언 값을 갖는다. - [[Enumerable]]의 값이 false인 경우 해당 프로퍼티는 for ... in문이나 Object.keys 메서드 등으로 열거할 수 없다. |
| [[Configurable]] | configurable | - 프로퍼티의 재정의 가능 여부를 나타내며 불리언 값을 갖는다. - [[Configurable]]의 값이 false인 경우 해당 프로퍼티의 삭제, 프로퍼티 어트리뷰트 값의 변경이 금지된다. 단, [[Writable]]을 false로 변경하는 것은 허용된다. |
16.3.2 접근자 프로퍼티
| 프로퍼티 어트리 뷰트 |
프로퍼티 디스크립터 객체의 프로퍼티 |
설명 |
| [[Get]] | get | 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수다. 즉, 접근자 프로퍼티 키로 프로퍼티 값에 접근하면 프로퍼티 어트리뷰트 [[Get]]의 값, 즉, getter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환된다. |
| [[Set]] | set | 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수다. 즉, 접근자 프로퍼티 키로 프로퍼티 값을 저장하면 프로퍼티 어트리뷰트 [[Set]]의 값, 즉 setter 함수가 호출되고 그 결과가 프로퍼티 값으로 저장된다. |
| [[Enumerable]] | enumerable | 데이터 프로퍼티의 [[Enumerable]]과 같다. |
| [[Configurable]] | configurable | 데이터 프로퍼티의 [[Configurable]]과 같다. |
16.4 프로퍼티 정의
프로퍼티 정의란 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다.
// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName', {
value: 'JoonHyuk',
writable: true,
enumerable: true,
configurable: true
});
Object.defineProperty(person, 'lastName', {
value: 'Eo'
});
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log('firstName', descriptor);
// firstName { value: 'JoonHyuk', writable: true, enumerable: true, configurable: true}
Object.defineProperties 메서드 사용
const person = {};
Object.defineProperties(person, {
// 데이터 프로퍼티 정의
firstName: {
value: 'JoonHyuk',
writable: true,
enumerable: true,
configurable: true
},
lastName: {
value: 'Eo',
writable: true,
enumerable: true,
configurable: true
},
// 접근자 프로퍼티 정의
fullName: {
// getter 함수
get() {
return `${this.firstName} ${this.lastName}`;
},
// setter 함수
set(name){
[this.firstName, this.lastName] = name.split(' ');
},
enumerable: true,
configurable: true
}
});
person.fullName = 'Haechan Kim';
console.log(person); // { firstName: 'Haechan', lastName: 'Kim', fullName: [Getter/Setter] }
16.5 객체 변경 방지
객체는 변경 가능한 값이므로 재할당 없이 직접 변경할 수 있다.
객체 변경 방지 메서드
| 구분 | 메서드 | 프로퍼티 추가 | 프로퍼티 삭제 |
프로퍼티 값 읽기 |
프로퍼티 값 쓰기 |
프로퍼티 어트리뷰트 재정의 |
| 객체 확장 금지 | Object.preventExtensions | X | O | O | O | O |
| 객체 밀봉 | Object.seal | X | X | O | O | X |
| 객체 동결 | Object.freeze | X | X | O | X | X |