객체에 설정할 수 있는 프로퍼티.
객체 프로퍼티는 플래그라는 특별한 속성 세 가지를 갖는다.
1) writable - true이면 값 수정 가능.
2) enumerable -true면 반복문 사용해 나열 가능.
3) configurable - true이면 프로퍼티 삭제나 플래그 수정 가능.
Object.getOwnPropertyDescriptor 메서드를 사용해 특정 프로퍼티에 대한 정보를 모두 얻기 가능.
let user = {
name: "John"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
alert( JSON.stringify(descriptor, null, 2 ) );
/* property descriptor:
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
*/
플래그 변경 => Object.defineProperty
Object.defineProperty(obj, propertyName, descriptor)
Writable플래그, 값 쓰지 못하게 변경하기
let user = {
name: "John"
};
Object.defineProperty(user, "name", {
writable: false
});
user.name = "Pete"; // Error: Cannot assign to read only property 'name'
enumerable 플래그
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
enumerable : false인 프로퍼티는 열거되지 않음. Object.keys에도 배제된다.
Configurable 플래그
false인 경우 프로퍼티 쓰기, 열거, 구성 불가. 주요 예) Math의 PI프로퍼티.
Object.defineProperties
프로퍼티 여러 개를 한 번에 정의 가능.
Object.defineProperties(obj, {
prop1: descriptor1,
prop2: descriptor2
// ...
});
//----
Object.defineProperties(user, {
name: { value: "John", writable: false },
surname: { value: "Smith", writable: false },
// ...
});
Object.getOwnPropertyDescriptors
프로퍼티 설명자를 전부 한꺼번에 가져올 수 있다.
특히, Object.defineProperties와 함께 사용하면 객체 복사 시 플래그도 함께 복사 가능.
let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
// 위 방법은 플래그 정보도 복사하기 위해서 사용하는 방법.
기존의 프로퍼티 복사 방법을 통한 객체 복사방법은 플래그 정보 복사가 안됬음
기존 방식)
for (let key in user) {
clone[key] = user[key]
}
접근자 프로퍼티 : getter , setter
let obj = {
get propName() {
// getter, obj.propName을 실행할 때 실행되는 코드
},
set propName(value) {
// setter, obj.propName = value를 실행할 때 실행되는 코드
}
};
실제 사용 예)
실제 값은 _name 프로퍼티에 저장되고, 값을 읽어올 때는 user.name(getter사용)으로 읽어옴.
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("입력하신 값이 너무 짧습니다. 네 글자 이상으로 구성된 이름을 입력하세요.");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // 너무 짧은 이름을 할당하려 함
호환성을 위해 접근자 프로퍼티 사용.
example) age값을 입력 받는 대신, Birthday를 입력받기로 수정한 경우 다음과 같이 코드 수정 가능.
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 역시 사용할 수 있습니다.
javascript.info - 9.클래스 (0) | 2022.12.30 |
---|---|
javascript.info - 프로토타입과 프로토타입 상속 (0) | 2022.12.30 |
javascript.info - 함수 심화학습(2) (0) | 2022.12.29 |
javascript.info - 함수 심화학습 (0) | 2022.12.29 |
javascript.info - 자료구조와 자료형 (0) | 2022.12.28 |