const object = {};
object.__proto__
프로퍼티의 상태란?
프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)를 말한다.
const product = {
price: 1000,
};
console.log(Object.getOwnPropertyDescriptor(product, "price"));
// 결과
{ value: 1000, writable: true, enumerable: true, configurable: true }
Object.getOwnPropertyDescriptor
- getOwnPropertyDescriptor 메서드를 호출할 때 첫 번째 매개 변수에는 객체의 참조를 전달하고, 두 번째 매개변수에는 프로퍼티 키를 문자열로 전달한다.
- 이 때, 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터(PropertyDescriptor) 객체를 반환한다.
- 만약 존재하지 않는 프로퍼티나 상속받은 프로퍼티일 경우 undefined가 반환된다.
const product = {
price: 1000,
};
product.createdAt = "2021-12-04";
console.log(Object.getOwnPropertyDescriptors(product));
// 결과
price: { value: 1000, writable: true, enumerable: true, configurable: true },
createdAt: {
value: '2021-12-04', writable: true, enumerable: true, configurable: true
}
const product = {
price: 1000,
createdAt: "2021-12-04",
get print() {
return `해당 물건의 가격은 ${this.createdAt}일 기준 ${this.price}원 입니다.`;
},
set setPrice(price) {
this.price = price;
},
set setCreatedAt(createdAt) {
this.createdAt = createdAt;
},
};
console.log(product.print);
product.setPrice = 2000;
product.setCreatedAt = "2021-12-05";
console.log(product.print);
// 결과
"해당 물건의 가격은 2021-12-04일 기준 1000원 입니다."
"해당 물건의 가격은 2021-12-05일 기준 2000원 입니다."
프로토타입(prototype)
- 프로토타입은 어떤 객체의 상위(부모) 객체의 역할을 하는 객체이다. 즉, 프로토 타입은 하위(자식) 객체에게 자신의 프로퍼티와 메서드를 상속한다. 상속을 받은 하위 객체는 자신의 프로퍼티 또는 메서드인 것처럼 자유롭게 사용할 수 있다.
- 프로토타입 체인은 프로토타입이 단방향 링크드 리스트 형태도 연결되어 있는 상속 구조를 말한다.
프로퍼티 구분
- 접근자 프로퍼티와 데이터 프로퍼티를 구별하는 방법은 다음과 같다.
Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'); // {enumerable: false, configurable: true, get: ƒ, set: ƒ} Object.getOwnPropertyDescriptor(function() {}, 'prototype'); // {value: {…}, writable: true, enumerable: false, configurable: false}
- 접근자 프로퍼티와 데이터 프로퍼티의 프로퍼티 디스크립터 객체의 프로퍼티가 다른 것을 알 수 있다.
const product = {};
Object.defineProperty(product, 'price', {
value: 1000,
writable: true,
enumerable: true,
configurable: true
});
Object.defineProperty(product, 'createdAt', {
value: "2021-12-04",
});
let descriptor = Object.getOwnPropertyDescriptor(product, 'price');
console.log('price', descriptor);
// 결과
price {value: 1000, writable: true, enumerable: true, configurable: true}
const createdAtDescriptor = Object.getOwnPropertyDescriptor(
product,
"createdAt"
);
descriptor = Object.getOwnPropertyDescriptor(product, 'createdAt');
console.log('createdAt', descriptor);
// 결과
createdAt {value: '2021-12-04', writable: false, enumerable: false, configurable: false}
product.price = 2000;
descriptor = Object.getOwnPropertyDescriptor(product, "price");
console.log("price", descriptor);
product.createdAt = "2021-12-05";
descriptor = Object.getOwnPropertyDescriptor(product, "createdAt");
console.log("createdAt", descriptor);
// 결과
price { value: 2000, writable: true, enumerable: true, configurable: true }
createdAt { value: '2021-12-04', writable: false, enumerable: false, configurable: false }
const product = {};
Object.defineProperties(product, {
price: {
value: 1000,
writable: true,
enumerable: true,
configurable: true,
},
createdAt: {
value: "2021-12-04",
},
print: {
get() {
return `해당 물건의 가격은 ${this.createdAt}일 기준 ${this.price}원 입니다.`;
},
},
setPrice: {
set(price) {
this.price = price;
},
},
});
console.log(product.print);
// 결과
"해당 물건의 가격은 2021-12-04일 기준 1000원 입니다."
const person = { name: "Lee" };
console.log(Object.isExtensible(person));
Object.preventExtensions(person);
console.log(Object.isExtensible(person));
person.job = "programmer";
console.log(person);
// 결과
true
false
{ name: "Lee" }
const person = { name: "Lee" };
console.log(Object.isSealed(person));
Object.seal(person);
console.log(Object.isSealed(person));
delete person.name;
console.log(person);
person.name = "kim";
console.log(person);
// 결과
false
true
{ name: 'Lee' }
{ name: 'kim' }
const person = { name: "Lee" };
console.log(Object.isFrozen(person));
Object.freeze(person);
console.log(Object.isFrozen(person));
delete person.name;
console.log(person);
person.name = "kim";
console.log(person);
console.log(Object.getOwnPropertyDescriptors(person));
// 결과
false
true
{ name: 'Lee' }
{ name: 'Lee' }
{
name: {
value: 'Lee',
writable: false,
enumerable: true,
configurable: false
}
}
const person = {
name: "Lee",
address: { city: "seoul" },
};
function freeze(obj) {
Object.keys(obj).forEach((key) =>
typeof obj[key] === "object" ? freeze(obj[key]) : Object.freeze(obj)
);
}
freeze(person);
console.log(Object.isFrozen(person.name));
console.log(Object.isFrozen(person.address.city));
person.name = "Kim";
person.address.city = "incheon";
console.log(person);
// 결과
true
true
{ name: 'Lee', address: { city: 'seoul' }}
5 7 10 16 22 38 41 + 27