16.1 내부 슬롯과 내부 메서드
- 내부 슬롯과 메서드는 JS 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드
- ECMAScript 사양에 등장하는
[[]] 로 감싼 이름들이 내부 슬록과 메서드
- 개발자가 직접 접근하거나 호출할 수 없음
- 단 일부 내부 슬롯과 메서드에 한하여 접근할 수 있는 수단 제공
16.2 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
JS 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의함
- 프로퍼티 상태 : 프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable0를 칭함
Object.getOwnPropertyDescriptor 메서드를 사용하면 프로퍼티 디스크럽터 객체 반환
16.3 데이터 프로퍼티와 접근자 프로퍼티
- 데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티 (지금까지 살펴본 모든 프로퍼티는 데이터 프로퍼티)
- 접근자 프로퍼티 : 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
데이터 프로퍼티
프로퍼티 어트리뷰트 — 프로퍼티 디스크립터 객체의 프로퍼티
- [[Value]] — value
- 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값
- 프로퍼티 키를 통해 값을 변경하면 [[Value]]에 값을 재할당
- 이때 프로퍼티가 없을시 동적 생성하고 생성한 프로퍼티 [[Value]]에 값을 저장
- [[Writable]] — writable
- 프로퍼티 값의 변경 가능 여부를 나타냄 (boolean)
- 값이 false 인 경우 해당 프로퍼티의 [[Value]]의 값을 변경할 수 없는 읽기 전용 프로퍼티가 됨
- [[Enumerable]] — enumerable
- 프로퍼티의 열거 가능 여부를 나타냄 (boolean)
- 값이 false 인 경우 해당 프로퍼티는 for .. in 문이나, Object,keys 메서드 등으로 열거할 수 없음
- [[Configurable]] — configurable
- 프로퍼티의 재정의 가능 여부를 나타냄 (boolean)
- 값이 false 인 경우 해당 프로퍼티의 삭제, 프로퍼티 어트리뷰트 값의 변경이 금지됨
- [[Writable]]이 true 인 경우 [[Value]]의 변경과 [[Writable]]을 false로 변경하는 것은 허용
접근자 프로퍼티
자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티
프로퍼티 어트리뷰트 — 프로퍼티 디스크립터 객체의 프로퍼티
- [[Get]] — get
- 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수
- 접근자 프로퍼티 키로 값에 접근하면 접근자 함수 getter가 호출되고 그 결과가 값으로 반환됨
- [[Set]] — set
- 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
- 접근자 프로퍼티 키로 값을 저장하면 setter 함수가 호출되고 결과가 값으로 저장됨
- [[Enumerable]] — enumerable
- 데이터 프로퍼티의 [[Enumerable]]과 같음
- [[Configurable]] — configurable
- 데이터 프로퍼티의 [[Configurable]]과 같음
접근자 프로퍼티와 데이터 프로퍼티 구별하는 방법
Object.getOwnPropertyDescriptor 메서드가 반환한 프로퍼티 디스크립터 객체의 프로퍼티가 서로 다름
16.4 프로퍼티 정의
새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것
Object.defineProperty 메서드를 사용하여 프로퍼티의 어트리뷰트 정의
- 정의 시 인수로는 객체의 참조와 데이터 프로퍼티의 키인 문자열, 프로퍼티 디스크립터 객체를 전달함
Object.defineProperty 메서드 이용하여 정의할 때 디스크립터 객체의 프로퍼티 일부 생략 가능
- value, get, set → undefined
- writable, enumerable, configurable → false
Object.defineProperties 메서드 사용시 여러 개의 프로퍼티를 한 번에 정의 가능
16.5 객체 변경 방지
- 객체는 변경 가능한 값이므로 재할당 없이 직접 변경할 수 있음
- 이때 사용하는 것이 객체 변경 방지 메서드로 금지하는 강도가 서로 다름
객체 확장 금지
확장이 금지된 객체는 프로퍼티 추가가 금지된다.
Object.preventExtensions 메서드 사용
- 프로퍼티 동적 추가와
Object.defineProperty 메서드 사용 금지
- 확장 가능 여부는
Object.isExtensible 메서드
객체 밀봉
밀봉된 객체는 읽기와 쓰기만 가능하다.
Object.seal 메서드 사용
- 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지
- 밀봉된 객체인지 여부는
Object.isSealed 메서드
객체 동결
동결된 객체는 읽기만 가능
Object.freeze 메서드 사용
- 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지, 프로퍼티 값 갱신 금지
- 동결된 객체인지 여부는
Object.isFrozen 메서드
불변 객체
- 위 세 개의 변경 방지 메서드들은 얕은 변경 방지로 직속 프로퍼티만 변경이 방지되고 중첩 객체에는 방지 불가
- 객체의 중첩 객체까지 동결하여 읽기 전용의 불변 객체 구현시 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 동결 메서드 호출해야 함