자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티( pseudo property )와 의사 메서드( psuedo method )를 내부 슬롯, 내부 메서드라고 한다. 이 들은 자바스크립트의 '내부 엔진' 이므로 직접적인 접근은 불가하지만 간접적으로 접근할 수 있는 수단을 제공한다.
프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
📌 Property Attribute
value, writable, enumerable, configurable
자바스크립트 엔진은 프로퍼티 생성시 프로퍼티의 상태를 나타내는 '프로퍼티 어트리뷰트( property attribute )'를 기본값으로 자동 정의한다. 이 어트리뷰트에는 value( 프로퍼티 값 ), writable( 값의 갱신 가능 여부 ), enumerable( 열거 가능 여부 )와 configurable( 재정의 가능 여부 )가 있다.
Object.getOwnPropertyDescriptor(참조할 객체명, '프로퍼티키')
메서드로 프로퍼티를 하나씩 확인할 수 있고, Object.getOwnPropertyDescriptors(참조할 객체명)
메서드로 모든 프로퍼티를 한번에 확인할 수 있다.
데이터 프로퍼티와 접근자 프로퍼티
1. 데이터 프로퍼티( data property )
키와 값으로 구성된 일반적인 프로퍼티이다. 'value', 'writable', 'enumerable', 'configurable' 로 이루어져 있다.
'value' 는 값에 접근하면 반환되는 값이다.
'writable' 는 값의 변경 가능 여부로 불리언 값을 가지고 있다. [[writable]]이 false 일 경우, 읽기 전용 프로퍼티( readonly )가 된다.
'enumerable' 는 열거 가능 여부로 불리언 값을 가지고 있다. [[enumerable]]이 false 일 경우, for ... in
문이나 Object.keys
메서드 등을 사용할 수 없다.
'configurable' 는 재정의 가능 여부로 불리언 값을 가지고 있다. [[configurable]]이 false일 경우, 프로퍼티 삭제, 값 변경이 금지된다.
위의 특징은 동적으로 추가된 프로퍼티에도 동일하게 작동한다.
const person = {
name: 'Tia'
};
person.age = 10;
console.log(Object.getOwnPropertyDescriptors(person));
/*
{
name: {value: 'Tia', writable: true, enumerable: true, configurable: ture},
age: {value: 10, writable: true, enumerable: true, configurable: true}
}
*/
2. 접근자 프로퍼티( accessor property )
자체적으로는 값을 갖지 않고, 다른 데이터 프로퍼티 값을 읽거나 저장할 때 호출되는 접근자 함수( accessor function )로 구성된 프로퍼티 이다. 'get', 'set', 'enumerable', configurable' 로 이루어져 있다.
'get' 은 프로퍼티 값을 읽을 때 호출되는 접근자 함수로 getter
함수를 호출하여 값을 반환한다.
'set' 은 프로퍼티 값을 저장할 때 호출되는 접근자 함수로 setter
함수를 호출하여 값을 저장한다.
'enumerable'과 'configurable' 은 데이터 프로퍼티와 동일하게 작동한다.
프로퍼티 정의
Object.defineProperty
, Object.defineProperties
메서드를 사용하여 프로퍼티의 어트리뷰트를 정의할 수 있다. 프로퍼티 디스크립터 객체에서 생략된 어트리뷰트는 정해진 기본값이 적용되는데, 'value', 'set', 'get'은 undefined
가 적용되고 'writable', 'enumerable', 'configurable'는 false
가 적용된다.
객체 변경 방지
얕은 변경 방지로 직속 프로퍼티에만 변경이 방지되고 중첩 객체까지는 영향을 주지 못한다. 중첩 객체에도 영향을 주고자 한다면 매번 메서드를 반복하여 활용하여야 한다.
Object.preventExtensions
: 객체의 확장 금지Object.isExtensible
로 확인Object.seal
: 객체 밀봉Objcet.isSealed
로 확인Object.freeze
: 객체 동결Object.isFrozen
으로 확인