프로퍼티 어트리뷰트
1. 내부 슬롯과 내부 메소드
- 내부 슬롯과 내부 메소드는 자바스크립트 엔진의 알고리즘을 설명하기 위해 ECMA 사양에서 사용하는 의사 프로퍼티와 의사 메소드 이다. [[]]
- 외부로 공개된 객체의 프로퍼티는 아니다.
- 간접적으로만 접근할 수 있다.
2. 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의
프로퍼티 상태?
프로퍼티의 값(value), 값의 갱신 가능여부(writable), 열거가능여부(enumberable), 재정의 가능여부(configurable)
프로퍼티 어트리뷰트
- 자바스크립트 엔진이 관리하는 내부 상태 값(meta-property)
- Object.getOwnPropertyDescriptor 메소드를 이용해 간접적으로 확인할 수 있다. (직접적 불가)
3. 데이터 프로퍼티와 접근자 프로퍼티
- 데이터 프로퍼티(date property) 키와 값으로 구성된 일반적인 프로퍼티
- 잡근자 프로퍼티(Accessor property) 자체적으로는 값을 갖지않고, 다른 데이터 프로퍼티 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
3.1 데이터 프로퍼티
데이터 프로퍼티 어트리뷰트는 자바스크립트 엔진이 프로퍼티를 생성할 때, 기본값으로 자동 정의된다.
| 프로퍼티 어트리뷰트 | 프로퍼티 디스크립터 객체의 프로퍼티 | 설명 |
|---|---|---|
| [[Value]] | vlaue | - 프로퍼티 키로 프로퍼티 값에 접근하면 반환되는 값 -프로퍼티 키로 프로퍼티 값을 저장하면 [[Value]]에 값을 저장한다. 프로퍼티가 없으면 프로퍼티를 생성하고 생성된 프로퍼티의[[Value]]에 값을 저장한다. |
| [[Writable]] | writable | - 프로퍼티 값의 변경 가능 여부를 나타내며 불리언 값을 갖는다. - false인 경우, 해당 프로퍼티의 [[Value]]의 값을 변경할 수 없는는 읽기 전용 프로퍼티가 된다. |
| [[Enumberable]] | enumberable | - 프로퍼티의 열거 가능여부를 나타내며 불리언 값을 갖는다. - false인 경우, 해당 프로퍼티는 for…in문이나 Object.keys 메소드 등으로 열거할 수 없다. |
| [[Configurable]] | configurable | - 프로퍼티의 재정의 가능 여부를 나타내며 불리언 값을 갖는다. - false인 경우, 해당 프로퍼티의 삭제, 프로퍼티 어트리뷰트 값의 변경이 금지된다. 단 [[Writable]]이 true인 경우, [[Value]]의 변경과 [[Writable]]을 false로 변경하는 것은 허용된다. |
1 | const person = { |
3.2 접근자 프로퍼티
자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티다.
getter, setter 함수라고도 부른다. 두 함수 모두 정의할 수 있고, 하나만 정의할 수도 있다.
프로퍼티 어트리뷰트 프로퍼티 디스크립터 객체의 프로퍼티 설명 [[Get]] get - 데이터 프로퍼티의 값을 저장할 때 호출
프로퍼티 키로 프로퍼티 값에 접근하면 프로퍼티 어트리뷰트 [[Get]]의 값, getter 함수가 호출, 그결과가 프로퍼티 값으로 반환된다.[[Set]] set 데이터 프로퍼티의 값을 저장할 때 호출
프로퍼티 어트리뷰트[[Set]]의 값, setter함수가 호출되고 그결과가 프로퍼티 값으로 저장된다.[[Enumberable]] enumberable 데이터 프로퍼티의 [[Enumerable]]와 같다. [[Configurable]] configurable 데이터 프로퍼티의 [[Configurable]]와 같다.
- 프로퍼티 키가 유효한지 확인한다. 문자열 또는 심볼이여야 한다.
- 프로토타입 체인에서 프로퍼티를 검색한다.
- 검색된 프로퍼티가 데이터 프로퍼티인지, 접근자 프로퍼티인지 확인한다.
- 프로퍼티 어트리뷰트 [[Get]]. getter 함수를 호출하여 그 결과를 반환한다.
4. 프로퍼티 정의
- 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트릴뷰트를 재정의 하는 것
- 객체의 프로퍼티가 어떻게 동작해야 하는지 명확히 정의할 수 있다.
- Object.defineProperty 메소드를 사용하면 프로퍼티의 어트리뷰트를 정의할 수 있다.
- 인수는 객체의 참조와 데이터 프로퍼티의 키인 문자열 그리고 프로퍼티 디스크립터 객체를 전달한다.
- Object.defineProperty 메소드로 프로퍼티 정의할 때, 프로퍼티 디스크립터 객체의 프로퍼티를 일부 생략할 수 있다.
| 프로퍼티 디스크립터 객체의 프로퍼티 | 대응하는 프로퍼티 어트리뷰트 | 디스크립터 객체의 프로퍼티 누락시 기본값 |
|---|---|---|
| value | [[Value]] | undifined |
| get | [[Get]] | undifined |
| set | [[Set]] | undifined |
| writable | [[Writable]] | false |
| enumberable | [[Enumberable]] | false |
| configurable | [[Configurable]] | false |
5. 객체 변경 방지
- 객체는 변경 가능한 값. 재할당 없이 직접 변경 가능
- Object.defineProperty or Object.defineProperties 메소드를 사용하여 프로퍼티 어트리뷰트를 재정의할 수 도있다.
- 자바스크립트는 객체의 변경을 방지할 수 있는 다양한 메소드를 제공
5.1 객체 확장 금지
- Object.preventExtensions 메소드는 객체의 확장을 금지
- 확장이 금지된 객체는 추가가 금지된다.
- 동적추가와, 메소드로 추가 둗가지 모두 금지
- 확장금지 객체 여부는 Object.isExtensible 메소드로 확인 가능하다
5.2 객체 밀봉
- Object.seal 메소드는 객체를 밀봉
- 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의를 금지한다.
- 밀봉된 객체는 읽기와 쓰기만 가능
- 밀봉 객체 여부는 Object.isSealed 메소드로 확인가능
5.3 객체 동결
- Object.freeze 메소드는 객체를 동결
- 프로퍼티 추가 삭제 금지, 재정의 금지, 갱신 금지
- 동결된 객체는 읽기만 가능
- Object.Frozen 메소드로 확인가능
5.4 불변 객체
- 위 메소드들은 얕은 변경방지(Shallow only) => 직속 프로퍼티에만 변경이 방지되고 중첩 객체 까지는 영향을 주지 못한다.
- 객체의 중첩 객체까지 동결하여 변경이 불가능한 읽기 전용의 불변객체를 구현하려면, 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메소드를 호출해야 한다.