내부 슬롯( internal slot )과 내부 메서드( internal method )란?
- 내부 슬롯과 내부 메서드는 자바스크립트 엔진 내부에서 사용되는 비공개 요소로서, ECMAScript 사양에서 사용하는 의사 프로퍼티( pseudo property )와 의사 메서드( pseudo method )입니다. ECMAScript 사양에 등장하는 이중 대괄호([[...]])로 감싼 이름들이 내부 슬롯과 내부 메서드입니다.
내부 슬롯과 내부 메서드 특징
- 내부 슬롯과 내부 메서드는 자바스크립트 엔진에서 실제로 동작하지만 개발자가 직접 접근할 수는 없습니다. 단, 일부 내부 슬롯과 내부 메서드에 한하여 간접적으로 접근할 수 있는 수단을 제공하고 있습니다. 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는데
__proto__
를 통해서 [[Prototype]]에 간접적으로 접근할 수 있습니다.
하지만, __proto__는 비표준으로써 권장되지 않기 때문에 Object.getPrototypeOf()와 Object.setPrototypeOf() 메서드를 사용하여 [[Prototype]] 내부 슬롯에 간접적으로 접근하는 것이 권장됩니다
프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
const person = {
name: "devhun",
};
// 프로퍼티 디스크립터 객체 반환
// {value: 'devhun', writable: true, enumerable: true, configurable: true}를 return
console.log(Object.getOwnPropertyDescriptor(person, "name"));
- 자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의합니다. 프로퍼티 상태란 프로퍼티의 값( value ), 값의 갱신 가능 여부( writable ), 열거 가능 여부( enumerable ), 재정의 가능 여부( configurable )를 말합니다.
프로퍼티 어트리뷰트는 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]이다. 따라서 프로퍼티 어트리뷰트에 직접 접근할 수 없지만 Object.getOwnPropertyDescriptor 메서드를 사용하여 return 받은 프로퍼티 디스크립터 객체를 통해 간접적으로 확인할 수 있습니다.
데이터 프로퍼티와 접근자 프로퍼티
- 프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있습니다.
- 데이터 프로퍼티와 접근자 프로퍼티를 구분하는 방법은 Object.getOwnPropertyDescriptor 메서드를 사용하여 return된 객체의 프로퍼티를 통해 구분할 수 있습니다.
데이터 프로퍼티
const obj = {
foo: 123,
};
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
console.log(descriptor);
// { value: 123, writable: true, enumerable: true, configurable: true }
- 키와 값으로 구성된 일반적인 프로퍼티입니다.
- 데이터 프로퍼티의 어트리뷰트는 [[Value]], [[Writable]], [[Enumerable]], [[Configuable]]로 구성됩니다.
접근자 프로퍼티
const person = {
firstName: "John",
lastName: "Doe",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
const [firstName, lastName] = name.split(" ");
this.firstName = firstName;
this.lastName = lastName;
}
};
const descriptor = Object.getOwnPropertyDescriptor(person, "fullName");
console.log(descriptor);
/*
{
get: ƒ fullName(),
set: ƒ fullName(name),
enumerable: true,
configurable: true
}
*/
- 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티입니다.
- 접근자 프로퍼티의 어트리뷰터는 [[Get]], [[Set]], [[Enumerable]], [[Configurable]]로 구성됩니다.
프로퍼티 정의
const player = {};
Object.defineProperty(player, "name", {
value: "devhun",
writable: true,
enumerable: true,
configuable: true,
});
const player = {};
Object.defineProperties(player, {
name: {
value: "devhun",
writable: true,
enumerable: true,
configuable: true,
},
age: {
value: 27,
writable: true,
enumerable: true,
configuable: true,
},
});
- Object.defineProperty, Object.defineProperties를 통해서 프로퍼티와 프로퍼티 어트리뷰트를 정의할 수 있습니다.
객체 변경 방지
프로퍼티 추가 | 프로퍼티 삭제 | 프로퍼티 값 읽기 | 프로퍼티 값 쓰기 | 프로퍼티 어트리뷰트 재정의 | ||
---|---|---|---|---|---|---|
객체 확장 금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
- 조건에 따라서 Object.preventExtensions, Object.seal, Object.freeze를 이용해서 객체의 변경을 방지할 수 있습니다. 다만 프로퍼티가 객체일 경우 해당 객체까지 적용되지 않기 때문에 해당 프로퍼티를 대상으로 추가적으로 호출해 주어야 합니다.
'Programming Language > JavaScript' 카테고리의 다른 글
함수와 일급 객체 (0) | 2022.12.07 |
---|---|
Math.random() 사용법과 주의사항 (0) | 2022.12.07 |
암묵적 전역( implicit global )이란? (0) | 2022.11.28 |
자바스크립트 생성자 함수에 관하여 (0) | 2022.11.21 |
var, let, const 타입에 관하여 (0) | 2022.11.20 |