Property flags and descriptors
객체에는 평소에는 보이지 않는 프로퍼티가 있다
writable
, enumerable
, configuable
, getter
, setter
인데 이에 대해 알아보도록 하자
1. property flags
1-1. writable
writable
이 true
이면 값을 수정할 수 있다
let user = {
name: "John"
};
Object.defineProperty(user, "name", {
writable: false
});
user.name = "Pete"; // Error: Cannot assign to read only property 'name'
따라서 위와 같이 false
로 설정해주면 에러가 발생한다
📌 에러는
strict mode
에서만 발생된다
1-2. enumerable
enumerable
이 true
이면 반복문을 사용해 나열할 수 있다
let user = {
name: "John",
toString() {
return this.name;
}
};
Object.defineProperty(user, "toString", {
enumerable: false
});
// 이제 for...in을 사용해 toString을 열거할 수 없게 되었습니다.
for (let key in user) alert(key); // name
toString
메서드는 반복문을 통해 열거 할 수 없음을 확인할 수 있다
1-3. configurable
configurable
이 true
이면 프로퍼티 삭제나 플래그 수정이 가능하다
let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');
alert( JSON.stringify(descriptor, null, 2 ) );
/*
{
"value": 3.141592653589793,
"writable": false,
"enumerable": false,
"configurable": false
}
*/
Math.PI = 3; // Error
// 수정도 불가능하지만 지우는 것 역시 불가능합니다.
즉 '영원히 변경할 수 없는' 객체를 만들수도 있다
2. getter, setter
객체의 프로퍼티는 두 종류로 나뉜다
-
데이터 프로퍼티(data property)로 일반적으로 사용했던 프로퍼티다
-
접근자 프로퍼티(accessor property)로 get, set의 역할을 담당한다
let obj = {
get propName() {
// getter, obj.propName을 실행할 때 실행되는 코드
},
set propName(value) {
// setter, obj.propName = value를 실행할 때 실행되는 코드
}
};
getter
메서드는 obj.propName
을 사용해 프로퍼티를 읽으려 할 때 실행되고
setter
메서드는 obj.propName = value
로 프로퍼티에 값을 할당하려 할 때 실행된다
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
},
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
alert(user.fullName); // John Smith
// 주어진 값을 사용해 set fullName이 실행됩니다.
user.fullName = "Alice Cooper";
alert(user.name); // Alice
alert(user.surname); // Cooper
이렇게 getter
, setter
메서드를 구현하면 객체에 fullName
이라는 가상의 프로퍼티가 생긴다
'가상'의 프로퍼티이기 때문에 읽고 쓸 순 있지만 실제로 존재하지는 않는다
이러한 getter
, setter
함수는 수정 불가능한 property를 만들때 좋다
예를 들어 생년월일을 입력하면 자동으로 나이 프로퍼티를 갖게 하고 싶은데 나이를 임의대로 바꿀 수 없게 할때
function User(name, birthday) {
this.name = name;
this.birthday = birthday;
// age는 현재 날짜와 생일을 기준으로 계산됩니다.
Object.defineProperty(this, "age", {
get() {
let todayYear = new Date().getFullYear();
return todayYear - this.birthday.getFullYear();
}
});
}
let john = new User("John", new Date(1992, 6, 1));
alert( john.birthday ); // birthday를 사용할 수 있습니다.
alert( john.age ); // age 역시 사용할 수 있습니다.
여기서 별도의 setter
함수가 없으므로 age
는 불러올 수만 있고 변경할 수는 없다
📌 접근자 프로퍼티에는 데이터 프로퍼티와 다르게
value
,writable
가 없는 대신get
,set
이라는 함수가 있는 것이다
*References
Author And Source
이 문제에 관하여(Property flags and descriptors), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ayaan92/Property-flags-and-descriptors저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)