ECMAScript 사양에서 자바스크립트 엔진의 내부 동작을 설명하기 위해 사용하는 개념으로,
개발자가 직접 접근하거나 호출하는 건 아니고 자바스크립트 엔진이 내부적으로만 사용하는 속성과 메서드입니다.
🔎 내부 슬롯이란?
자바스크립트 엔진이 각 객체의 상태를 관리하기 위해 사용하는 숨겨진 속성
[[Prototype]]
⇒ Object.getPrototypeof()
메서드 / __proto__
프로퍼티 제공🔎 내부 메서드란?
특정 동작을 수행하기 위해 엔진 내부에서 호출되는 함수
new
연산자와 함께 생성자 함수 호출 ⇒ 내부 메서드 [[Constructor]]
실행Function.prototype.call()
/ Function.prototype.apply()
⇒ 내부에서 [[Call]]
메서드 호출🔎 프로퍼티 어트리뷰트란?
객체의 프로퍼티에 대한 상태
🔎 프로퍼티 디스크립터 객체란?
프로퍼티 어트리뷰트 정보를 객체로 표현한 것
value
/ writable
/ enumerable
/ configurable
Object.getOwnPropertyDescriptor(객체명, 속성명 문자열)
: 프로퍼티 어트리뷰트 확인Object.getOwnPropertyDescriptor()
메서드는 객체 자신이 직접 소유하고 있는 프로퍼티만을 대상으로 하기 때문에 상속받는 프로퍼티에 대해서는 정보를 제공하지 않습니다.Object.getOwnPropertyDescriptors(객체명)
: 여러 프로퍼티 어트리뷰트 한번에 확인🔎 데이터 프로퍼티란?
키와 값으로 구성된 일반적인 프로퍼티
[[Value]]
: 프로퍼티의 값[[Writable]]
: 값의 갱신 가능 여부[[Enumerable]]
: 열거 가능 여부[[Configurable]]
: 재정의 가능 여부const person = {
name: '철수'
};
person.age = 20
console.log(Object.getOwnPropertyDescriptors(person));
{
name: { value: '철수', writable: true, enumerable: true, configurable: true },
age: { value: 20, writable: true, enumerable: true, configurable: true }
}
🔎 접근자 프로퍼티란?
다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티
get
이나 set
키워드가 붙은 함수 ⇒ 각각 getter
함수, setter
함수[[Get]]
: 값을 읽을 때 호출되는 접근자 함수 (getter 함수)[[Set]]
: 값을 저장할 때 호출되는 접근자 함수 (setter 함수)[[Enumerable]]
: 위와 동일[[Configurable]]
: 위와 동일 [[Get]]
, [[Set]]
을 함께 정의 ⇒ 동일한 이름의 getter와 setter는 하나의 프로퍼티const person = {
firstName: 'Ungmo',
lastName: 'Lee',
get fullName() {
return `${this.firstName} ${this.lastName}`
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
}
}
console.log(Object.getOwnPropertyDescriptor(person, 'fullName'));
{
get: [Function: get fullName],
set: [Function: set fullName],
enumerable: true,
configurable: true
}
person.personInfo = 'Heegun Lee'; // setter 호출
console.log(person.fullName); // getter 호출
Object.getOwnPropertyDescriptor
가 반환하는 프로퍼티 디스크립터 객체로 구분 가능const obj = { key: 'value' };
console.log(Object.getOwnPropertyDescriptor(obj, 'key'));
// { value: 'value', writable: true, enumerable: true, configurable: true }
const obj = {
get key() {
return 'value';},
set key(value) {
console.log('setter called');
}
};
console.log(Object.getOwnPropertyDescriptor(obj, 'key'));
// { get: [Function: get key], set: [Function: set key], enumerable: true, configurable: true }
🔎 프로퍼티 정의란?
새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것
Object.defineProperty(객체명, 속성명 문자열, 프로퍼티 디스크립터 객체)
: 프로퍼티 어트리뷰트 정의const person = {};
Object.defineProperty(person, 'firstName', {
value: 'Ungmo',writ
enumerable: true,
configurable: true
});
Object.defineProperty(person, 'lastName', {
value: 'Lee'
});
Object.defineProperty(person, 'fullName', {
get() {
return `${this.firstName} ${this.lastName}`
},
set(name) {
[this.firstName, this.lastName] = name.split(' ');
},
enumerable: true,
configurable: true
});
Object.defineProperties(객체명, 프로퍼티 디스크립터 객체)
: 여러 프로퍼티 어트리뷰트 한번에 정의const person = {};
Object.definedProperties(person, {
데이터 프로퍼티 이름: { ... },
데이터 프로퍼티 이름: { ... },
접근자 프로퍼티 이름: { ... },
});
구분 | 메서드 | 속성 추가 | 속성 삭제 | 속성 값 읽기 | 속성 값 쓰기 (갱신) | 어트리뷰트 재정의 |
---|---|---|---|---|---|---|
객체 확장 금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
객체 확장 금지 === 프로퍼티 추가 금지
관련 메서드
Object.preventExtensions(객체)
: 확장 금지 선언Object.isExtensible(객체명)
: 확장 가능 여부 확인Object.seal(객체)
: 밀봉 선언Object.isSealed(객체명)
: 밀봉 여부 확인Object.freeze(객체)
: 동결 선언Object.isFronzen(객체명)
: 동결 여부 확인