프로퍼티 어트리뷰트를 알기 전 알아야 할 키워드
내부 슬롯
과 내부 메서드
는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 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 |