자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드이며, [[...]] 같이 이중 대괄호로 감싼 이름들이 내부슬롯과 내부 메서드다.
👉 쉽게 말하자면, ECMAScript 문서에서 자바스크립트 내부 동작의 설명을 위해 정의해 놓은 가상 메소드
const o = {};
// 내부 슬롯은 자바스크립트 엔진의 내부 로직이므로 직접 접근 X
o.[[Prototype]] // -> Uncaught SyntaxError: Unexpected token '['
// 간접적으로 접근할 수 있는 수단을 제공한다.
o.__proto__ // Object.prototype
📄 prototype 의미는? 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어있고 이 부모 객체를 프로토타입이라고 한다.
자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의힌다.
const person = {
name: 'Lee'
};
// 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다.
console.log(Object.gerOwnpropertyDescriptor(person, 'name'));
// {value: "Lee", writable: true, enumeravble: true, configurable: true}
👉 쉽게 말하자면, Object.getOwnPropertyDescriptor()메서드는 모든 프로퍼티의 프로퍼티 어트리뷰트정보를 제공하는 프로퍼티 디스크립터 객체들을 반환한다.
만약 존재하지 않는 프로퍼티나 상속받은 프로퍼티에 대한 디스크립터를 요구하면 undefined를 반환함
📄: 프로퍼티 어트리뷰트란? 이러한 객체 내부의 각각의 프로퍼티들에 대해서 자바스크립트 엔진이 관리하는 속성값이다.
const person = {
name: "Lee",
};
person.age = 20;
console.log(Object.getOwnPropertyDescriptor(person));
/*
name: {value: 'Lee', writable: true, enumerable: true, configurable: true }
age: {value: '20', writable: true, enumerable: true, configurable: true }
// 일반 객체의 __proto__는 접근자 프로포티
Object.gerOwnpropertyDescriptor(Object.prototupe, '__proto__'));
// {ger: f, set: f , enumerable: flase, cofigurable: true}
// 함수 객체의 prototypedms 데이터 프로퍼티
Object.gerOwnpropertyDescriptor(function() {}, 'prototype');
// {value: {...}, writable: true, enumerable: flase, cofigurable: false}
const person = {};
// 데이터 프로퍼티 정의
Object.defineProperty(person, "firstName", {
value: "KIM",
writable: true,
enumerable: true,
configurable: true,
});
Object.defineProperty(person, "lastName", {
value: "LEE",
});
const descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
console.log(`firstName : ${descriptor}`);
// firstName {value: "LEE", writable: true, enumerable: true, configurable: true}
[[value]]
: 생략 했을때 undefined
가 기본값이다.
[[Enumerable]]
: false
인 경우, 열거가 불가능하다.
[[Writable]]
: false` 인 경우, 값 변경이 불가능하다. 변경을 하려고 시도해도 무시한다.
[[Copnfigurable]]
: false
인 경우, 프로퍼티 삭제가 불가능하다. 이 역시 삭제하려고 시도해도 무시함
객체는 기본적으로 값의 변경이 가능하기 때문에 프로퍼티 값 추가, 삭제, 갱신이 가능하다.
메서드를 사용하여 프로퍼티 어트리뷰트를 재정의할 수도 있다.
구분 | 메서드 | 프로퍼티 추가 | 프로퍼티 삭제 | 프로퍼티 값 읽기 | 프로퍼티 값 쓰기 | 프로퍼티 어트리뷰트 재정의 |
---|---|---|---|---|---|---|
객체 확장 금지 | Object.preventExtensions() | X | O | O | O | O |
객체 밀봉 | Object.seal() | X | X | O | O | X |
객체 동결 | Object.freeze() | X | X | O | X | X |
확장이 금지된 객체는 프로퍼티 추가가 금지된다.
👉 확장 가능 객체인지 여부는Object.isExtensible
메서드로 확인
밀봉된 객체는 읽기와 쓰기만 가능하다.
👉 확장 가능 객체인지 여부는Object.isSealed
메서드로 확인
동결된 객체는 읽기 전용(Read-Only)이다.
👉 확장 가능 객체인지 여부는Object.isFrozen
메서드로 확인
변경 방지 메서들은 얕은 변경 방지로 직속 프로퍼티만 변경 방지됩니다. 중첩 객체는 제한할 수 없다.
👉 변경이 불가능한 읽기 전용의 불변객체로 구현하려면 객체 값으로 갖는 모둔 프로퍼트를 재귀적으로Object.freexe
메서드를 호출해야함
Object.getOwnPropertyDescriptor()란?
프로퍼티 어트리뷰트(feat. 내부 슬롯, 내부 메소드)