
프로퍼티 어트리뷰트를 알기 전 알아야 할 키워드
내부 슬롯과 내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드다.
| Internal Method | Signature |
|---|---|
| [[GetPrototypeOf]] | ( ) → Object | Null |
| [[SetPrototypeOf]] | (Object | Null) → Boolean |
| [[IsExtensible]] | ( ) → Boolean |
| [[PreventExtensions]] | ( ) → Boolean |
| [[GetOwnProperty]] | (propertyKey) → Undefined | Property Descriptor |
| [[DefineOwnProperty]] | (propertyKey, PropertyDescriptor) → Boolean |
| [[HasProperty]] | (propertyKey) → Boolean |
| [[Get]] | (propertyKey, Receiver) → any |
| [[Set]] | (propertyKey, value, Receiver) → Boolean |
| [[Delete]] | (propertyKey) → Boolean |
| [[OwnPropertyKeys]] | ( ) → List of propertyKey |
이중 대괄호로 감싼 이름들이 내부 슬롯과 내부 메서드
const o = {};
// 내부 슬롯 직접 접근 - 제공 안함
o.[[Prototype]] // SyntaxError
// 내부 슬롯 간접적 접근 - 제공 함
o.__proto__ // Object.prototype
자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
| 프로퍼티의 상태 | 프로퍼티 어트리뷰트 | 기본 값 |
|---|---|---|
| 프로퍼티의 값 | [[value]] | |
| 값의 갱신 가능 여부 | [[Writable]] | true |
| 열거 가능 여부 | [[Enumerable]] | true |
| 재정의 가능 여부 | [[Configurable]] | true |
Object.getOwnPropertyDescriiptor 메서드 : 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다. (프로퍼티 설명자 객체 라고 해석하면 될까..?)

undefined

프로퍼티 디스크립터 객체
데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티
접근자 프로퍼티 : 자체적으로 값을 갖고 있지 않고, 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
| 프로퍼티 어트리뷰트 | 설명 |
|---|---|
| [[enumerable]] | 데이터 프로퍼티 것과 동일 |
| [[configurable]] | 데이터 프로퍼티 것과 동일 |
| [[get]] | 데이터 프로퍼티의 값을 읽는 접근자 함수 |
| [[set]] | 데이터 프로퍼티의 값을 저장 접근자 함수 |
const person = {
firstName : 'minsu',
lastName: 'kim',
get fullName() {return `${this.firstName} ${this.lastName}`},
set fullName(name) {[this.firstName, this.lastName] = name.split(' ')}
}
person.fullName = 'Ungmo Lee'
console.log(person.fullName)// Ungmo Lee
console.log(Object.getOwnPropertyDescriptor(person, 'firstName')) // {value: 'Ungmo', writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(person, 'fullName')) // {enumerable: true, configurable: true, get: ƒ, set: ƒ}
프로토 타입: 어떤 객체의 상위 객체의 역할을 하는 객체.
- 하위 객체에게 자신의 프로퍼티와 메서드를 상속
- 상속받은 하위 객체는 자신의 프로퍼티 또는 메서드 인 것 처럼 자유롭게 사용
프로토 체인: 프로토 타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속 구조
- 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티 또는 메서드가 없다면 프로토타입 체인을 따라 프로토타입의 프로퍼티나 메서드를 차례대로 검색한다.
자식에게 물려주는 방법
// 1. 생성자 함수를 사용한 상속
// 부모
function character (){
this.q = 'skill1'
this.w = 'skill2'
}
// 자식
let character1 = new character()
// 2. prototype (유전자 같은 느낌..)
// 부모
function character (){
this.q = 'skill1'
this.w = 'skill2'
}
// 유전
character.prototype.lastName = 'kim'
// 자식
let character1 = new character()
console.log(character1.__proto__.lastName) // kim
// 프로토 체인 발생 - 없으면 부모 유전자까지 싹 다 뒤짐
console.log(character1.__proto__.firstName) // undefined
let test = [1,2,3];
test.sort() // array 자료에 sort를 붙일 수 있는 이유가 뭘까?
test.length // array 자료에 length 붙일 수 있는 이유가 뭘까?
let test = new Array(1,2,3);
// 위의 array 선언은 인간의 편리한 방식이고, 밑은 컴퓨터의 방식이다.
// new 는 자식을 뽑기 위함이고, 이는 곧 부모의 유전자들도 들고 온다는 소리다.!
검증


// 이런식으로 내가 자주 쓰는 것을 추가해서 쓸 수 있다.
Array.prototype.testFunction = function(){return 1}

프로퍼티 정의 :새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의 하는 것
const person = {};
Object.defineProperty(person, 'lastName', {value : 'Lee'})

프로퍼티 어트리뷰트 값에 따라 제약을 컨트롤 한다.
(프로퍼티 디스크립터 객체의 프로퍼티 생략)
| 프로퍼티 어트리뷰트 | 생략했을 때의 기본값 |
|---|---|
| [[value]] | undefined |
| [[get]] | undefined |
| [[set]] | undefined |
| [[writable]] | false |
| [[writable]] | false |
| [[configurable]] | false |
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 |