Descriptor 속성들
- Object.defineProperty 의 3번째 파라미터에 들어가는 내용이다.
- 객체의 프로퍼티는
descriptor
를 갖는다. - 우리는 보통 객체 프로퍼티의
key
와value
만 설정해주기 때문에descriptor
를 직접 볼 일은 많지 않다. descriptor
에는 아래의 옵셔널 속성이 존재한다.value
: 프로퍼티 값writable
: 프로퍼티의 수정 가능 여부enumerable
: 프로퍼티의 열거(iterate) 가능 여부configurable
: 프로퍼티의 삭제 혹은 수정 가능 여부 (writable
보다 더 엄격한 버전)
Object.defineProperty(obj, prop, descriptor);
configurable
- 프로퍼티의 속성을 변경할 수 있는지의 여부이다.
- 기본 값은
false
이다. false
라면,- 한번
false
로 설정하면 바꾸지도 못한다. - 프로퍼티를 지우지도 못하고, 다른
descriptor
옵션을 변경하지도 못한다.
- 한번
const object1 = {};
Object.defineProperty(object1, "property1", {
value: 42,
configurable: false,
});
object1.property1 = 77; // strict 모드였다면, 예외를 던진다.
console.log(object1.property1); // expected output: 42
delete object1.property1; // returns false, 지워지지 않는다.
console.log(object1); // {property1: 42}, 지워지지 않았다.
// 한번 `false` 라면, 다시 `true` 로 바꿀 수 없다.
Object.defineProperty(object1, "property1", {
value: 42,
configurable: true,
});
/*
Uncaught TypeError: Cannot redefine property: property1
at Function.defineProperty (<anonymous>)
at <anonymous>:1:8
*/
enumerable
for ... in
과 같은 문법으로 순회 시킬 때, 열거에 응하는지 여부이다.- 기본 값은
true
이다.
const object = {
a: 1,
b: 2,
};
Object.defineProperty(object, "c", {
value: 3,
enumerable: false,
configurable: true,
});
Object.defineProperty(object, "d", {
value: 4,
enumerable: true,
});
const arr = [];
for (const p in object) {
arr.push(p);
}
console.log(arr); // ['a', 'b', 'd']
console.log(object.c); // 3
Object.defineProperty(object, "c", {
value: 3,
enumerable: true,
});
for (const p in object) {
arr.push(p);
}
console.log(arr); // ['a', 'b', 'd', 'a', 'b', 'c', 'd']
- 프로퍼티
c
는 열거 가능하지 않기 때문에, 처음for ... in
에서 순회에 걸리지 않는다. - 그러나 이후의
for ... in
에서는enumerable: true
로 세팅해주었기 때문에, 순회에 걸린다.
value
- 값을 의미한다.
number
,object
,function
등 다 가능하다.- 기본 값은
undefined
이다.
writable
true
라면, 할당자 연산자 를 통해 프로퍼티의 값을 변경 가능하다.- 기본 값은
false
이다. configurable
이true
라면,Object.defineProperty()
로 재수정 가능하다.
접근자 설명자 (Accessor descriptor
)
Access descriptor
란, 접근 시에 부가적으로 적용되는 로직이다.
get
(getter
)
const user = {
real_id: "n00nietzsche",
};
Object.defineProperty(user, "public_id", {
get() {
const { real_id } = this;
const secret_length = 3;
return `${real_id.substring(0, real_id.length - secret_length)}${"*".repeat(
secret_length
)}`;
},
});
console.log(user.public_id); // n00nietzs***
public_id
값을 불러왔을 때,real_id
를 모자이크 시킨 형태로 출력하고 싶다면, 위와 같은getter
를 사용할 수 있다.
set
(setter
)
const user = {
real_id: "n00nietzsche",
};
Object.defineProperty(user, "public_id", {
get() {
const { real_id } = this;
const secret_length = 3;
return `${real_id.substring(0, real_id.length - secret_length)}${"*".repeat(
secret_length
)}`;
},
set() {
throw "it is impossible to set public_id directly.";
},
});
user.public_id = "ABC"; // Uncaught it is impossible to set public_id directly.
Object.defineProperty(user, "real_id", {
set(value) {
if (value.length < 4) {
throw "real_id must be longer than 4 characters.";
}
return value;
},
});
user.real_id = "123"; // Uncaught real_id must be longer than 4 characters.
- 값을 할당할 때, 제약조건이나 추가적인 prefix, postfix 등을 더해 줄 수 있다.
반응형
'자바스크립트 > 개념' 카테고리의 다른 글
자바스크립트의 Symbol.toPrimitive 란? (0) | 2023.01.01 |
---|---|
데이터 프로퍼티 (data property)와 접근자 프로퍼티 (accessor property) 란? (0) | 2023.01.01 |
Symbol.species 심볼과 용례 (0) | 2022.12.24 |
오브젝트 리터럴 ('{}') 이 new Object() 보다 빠른 이유 (0) | 2022.12.22 |
Array.prototype.sort() 자세히 알아보기 (0) | 2022.12.20 |