객체에 담긴 자료를 프로퍼티라고 하고 프로퍼티는 '키: 값'의 구조를 가짐.
하지만 객체 프로퍼티는 값(value)과 함께 플래그(flag)라 불리는 속성 세 가지를 가짐.
-
평범한 방식으로 프로퍼티를 만들면 해당 프로퍼티의 플래그는 모두 true이며 언제든 수정이 가능하다.
플래그를 얻는 메서드
Object.getOwnPropertyDescriptor(obj, propertyName);
// obj : 정보를 얻고자 하는 객체
// propertyName : 정보를 얻고자 하는 객체 내 프로퍼티
메서드를 호출하면 프로퍼티 설명자"desriptor"라고 불리는 객체가 반환되고 여기에 프로퍼티 값과 플래그 정보가 있음.
-
let user = {
name: "friday"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);

- writable : true면 값을 수정할 수 있다 / false면 읽기만 가능
- enumerable : true면 반복문을 사용해 나열 가능 / false 면 나열 불가능.
- configurable : true면 프로퍼티 삭제나 플래그 수정 가능 / false면 불가능
플래그를 변경하는 메서드
Object.defineProperty(obj, propertyName, descriptor)
// obj, propertyName : 설명자를 적용하고 싶은 객체와 객체 프로퍼티
// descriptor : 적용하고자 하는 프로퍼티 설명자
객체에 해당 프로퍼티가 있으면 플래그를 변경해주며,
프로퍼티가 없으면 인수로 넘겨받은 정보를 이용해 새로운 프로퍼티를 생성.
이때 플래그 정보가 없으면 값이 자동으로 false가 된다.
let user = {}; // 빈 객체 생성
Object.defineProperty(user, "name", {value: "friday"});
// 객체 user에 프로퍼티 name을 추가하고 friday 값 할당
console.log(user); // friday
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);
// defineProperty로 프로퍼티를 생성했지만 플래그를 명시하지 않았기 때문에
// 모든 플래그가 false.
Object.defineProperty(user, "age", {value: "32", writable: true, enumerable: true, configurable: true});
// 프로퍼티를 추가할 때 각 플래그의 값은 명시해줘야 함.
let descriptor2 = Object.getOwnPropertyDescriptor(user, 'age');
console.log(descriptor2);

플래그 값을 명시하지 않은 name은 플래그 값이 모두 false
-
플래그 값을 명시한 age는 모든 플래그 값이 true
writable 플래그
프로퍼티의 값 수정을 제어하는 플래그
let user = {}; // 빈 객체 생성
Object.defineProperty(user, "name", {value: "friday", enumerable: true, configurable: true});
// writable의 값을 명시하지 않았기 때문에 false.
console.log(user.name); // friday
user.name = 'monday'; // 엄격모드 : error, 비엄격모드 : error는 안 나지만 변경 불가능.
console.log(user.name); // friday
enumerable 플래그
for...in으로 객체 내 프로퍼티를 순회 호출 여부를 제어하는 플래그
let user = {
name: 'friday',
age: 32,
height: 184,
weight: 80,
};
for(let i in user) { // i: 키, user[i]: 값
console.log(`${i}:${user[i]}`);
}
Object.defineProperty(user, "name", {enumerable: false});
for(let i in user) { // i: 키, user[i]: 값
console.log(`${i}:${user[i]}`);
}
// enumerable의 값이 false가 된 name은 반복문으로 순회 불가능.
configurable 플래그
프로퍼티의 삭제나 플래그 수정 여부를 제어하는 값( configurable의 값이 false면 defineProperty로도 수정이 불가능하기 때문에 수정, 제거가 불가능한 프로퍼티 생성 가능 )-*대표적으로 내장 객체 Math의 프로퍼티 PI가 있음

configurable이 false면 플래그의 삭제나 값 수정이 불가능.
(writable의 경우 true에서 false로 수정은 가능하지만 false에서 true로의 수정은 불가능.)
접근자 프로퍼티 get / set 을 변경할 수 없지만 새롭게 만드는 것은 가능.
Object.defineProperties
여러 프로퍼티를 한 번에 정의할 수 있는 메서드
-
Object.getOwnPropertyDescriptors
여러 프로퍼티의 설명자를 한 번에 호출하는 메서드.
let user = {}; // 빈 객체 생성.
Object.defineProperties(user, {
name: { value: 'kgh', writable: true, enumerable: true, configurable: true },
age: { value: 32, writable: true },
height: { value: 180, enumerable: true },
})
console.log(Object.getOwnPropertyDescriptors(user));

Object.defineProperties
Object.getOwnPropertyDescriptors
플래그 포함 객체 복사
-
for ...in을 사용한 객체 복사는 플래그 정보를 복사하지 않고, 심볼형 프로퍼티도 놓치지만
위 두 메서드를 조합해서 객체를 복사하면 플래그, 심볼형 프로퍼티를 포함한 모든 설명자 전체를 반환.
바로 위 설명의 user 객체를 복사해보자
let clone = Object.defineProperties({},
Object.getOwnPropertyDescriptors(user)
)
console.log(clone);


'JavaScript' 카테고리의 다른 글
| [JavaScript] 전개 구문 (spread syntax) _ more (0) | 2022.12.07 |
|---|---|
| [JavaScript] 배열의 메서드 종류_more (0) | 2022.12.07 |
| [JavaScript] 프로토타입(prototype) 상속 (0) | 2022.12.06 |
| [JavaScript] 배열 (array) (0) | 2022.12.06 |
| [JavaScript] 구조 분해 할당 (0) | 2022.12.06 |