자바스크립트에서 프로퍼티란
프로퍼티란 속성이란 뜻으로 자바스크립트에서 객체 내부의 속성을 의미한다.
기본적으로 자바스크립트에서 객체를 만든다면 Key와 value 한쌍으로 구성이 된다.
let person = { name : 'Lee' };
해당 person 객체의 name이 프로퍼티인 것이다.
객체에 프로퍼티는 동적으로 추가도 가능하고 delete로 삭제도 가능한데 이는 기본적으로 객체의 프로퍼티를 생성할 때 자동으로 정해지는 프로퍼티 어트리뷰트의 설정이 되어 있다.
프로퍼티 애트리뷰트는 자바스크립트 엔진이 관리하는 프로퍼티의 내부 슬롯( 프로퍼티값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부 )를 의미한다. 이는 직접 접근은 할 수 없지만 Object.getOwnPropertyDescriptor메서드를 통해 간접적으로 접근할 수 있다.
프로퍼티 애트리뷰트 종류
프로퍼티 애트리뷰트 | 프로퍼티 디스크립터 프로퍼티 | 설명 |
[[Value]] | value | 프로퍼티 키로 반환되는 값 |
[[Writable]] | writable | 해당 프로퍼티 값의 변경 가능 여부(false,true). false인 경우 읽기 전용 프로퍼티가 된다. |
[[Enumerable]] | enumerable | 프로퍼티의 열거 가능 여부(true,false). false인 경우 for문이나 Object.key로 확인 불가능 |
[[Configurable]] | configurable | 프로퍼티의 재정의 가능여부(true,false) |
프로퍼티 애트리뷰트 출력
let person = { name : 'Lee' };
console.log(Object.getOwnPropertyDescriptor(person,'name'));
/**
{ value: 'Lee', writable: true, enumerable: true, configurable: true }
*/
person.age = 20;
console.log(Object.getOwnPropertyDescriptors(person));
/**
{
name: {
value: 'Lee',
writable: true,
enumerable: true,
configurable: true
},
age: { value: 20, writable: true, enumerable: true, configurable: true }
}
*/
접근자 프로퍼티
접근자 프로퍼티는 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값으 ㄹ읽거나 저장할 때 사용하는 접근자 함수로 구성된다.
프로퍼티 어트리뷰트 | 프로퍼티 디스크립트 프로퍼티 | 설명 |
[[Get]] | get | 접근자 프로퍼티를 통해 프로퍼티 값을 읽을 때 호출되는 접근제어자 함수 |
[[Set]] | set | 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근제어자 함수 |
[[Enumerable]] | enumeable | 데이터 프로퍼티 [[Enumerable]]과 동일 |
[[Configurable]] | configurable | 데이터 프로퍼티 [[Configurable]]과 동일 |
접근자 프로퍼티 예제
const person = {
firstName : 'HS',
lastName : 'Kim',
get fullName(){
return `${this.firstName} ${this.lastName}`;
},
set fullName(name){
[this.firstName, this.lastName] = name.split(' ');
}
};
console.log(person.firstName + ' ' + person.lastName); // HS Kim
person.fullName = 'Zo SY';
console.log(person);
// { firstName: 'Zo', lastName: 'SY', fullName: [Getter/Setter] }
console.log(person.fullName); // Zo SY
let discriptor = Object.getOwnPropertyDescriptor(person,'firstName');
console.log(discriptor);
// { value: 'Zo', writable: true, enumerable: true, configurable: true }
discriptor = Object.getOwnPropertyDescriptor(person,'fullName');
console.log(discriptor);
/**
{
get: [Function: get fullName],
set: [Function: set fullName],
enumerable: true,
configurable: true
}
*/
프로퍼티 정의 방법
객체를 생성할 때 프로퍼티를 정의하는 방법과 동적으로 person.age = 20과 같이 정의를 해왓는데 이처럼 정의를 하게 되면 앞서 설명한 프로퍼티 애트리뷰트는 모두 true가 된다. 프로퍼티 애트리뷰트를 바꾸면서 정의하기 위해선 Object.defineProperty메서드를 사용하면 된다.
예제 코드
const person = {};
Object.defineProperty(person,'firstName',{
value : 'HS',
writable : true,
enumerable : true,
configurable : true
});
Object.defineProperty(person,'lastName',{
value : 'Kim',
writable : false,
enumerable : false,
configurable : false
});
let discriptor = Object.getOwnPropertyDescriptor(person,'firstName');
console.log(discriptor);
// { value: 'HS', writable: true, enumerable: true, configurable: true }
discriptor = Object.getOwnPropertyDescriptor(person,'lastName');
console.log(discriptor);
// { value: 'Kim', writable: false, enumerable: false, configurable: false }
console.log(Object.keys(person)); // [ 'firstName' ]
person.lastName = 'Lee'; // 값 변경X
delete person.lastName; // 값 삭제X
discriptor = Object.getOwnPropertyDescriptor(person,'lastName');
console.log(discriptor);
// { value: 'Kim', writable: false, enumerable: false, configurable: false }
Object.defineProperty(person,'fullName',{
get(){
return `${this.firstName} ${this.lastName}`;
},
set(name){
[this.firstName, this.lastName] = name.split(' ');
},
enumerable : true,
configurable : true
});
discriptor = Object.getOwnPropertyDescriptor(person,'fullName');
console.log(discriptor);
/**
{
get: [Function: get],
set: [Function: set],
enumerable: true,
configurable: true
}
*/
person.fullName = 'Zo SH';
console.log(person.fullName); // Zo Kim
프로퍼티 디스크립터 객체 프로퍼티
프로퍼티 디스크립터의 프로퍼티 | 대응하는 프로퍼티 애트리뷰트 | 생략했을 때 기본값 |
value | [[Value]] | undefined |
get | [[Get]] | undefined |
set | [[Set]] | undefined |
writable | [[Writable]] | false |
enumerable | [[Enumerable]] | false |
configurable | [[Configurable]] | false |
위 예제코드는 여러 프로퍼티를 각자 정의 햇는데 한번에도 가능하다.
const person = {};
Object.defineProperties(person,{
fistName : {
value : 'Kim',
writable : true,
enumerable : true,
configurable : true
},
lastName : {
value : 'HS',
writable : true,
enumerable : true,
configurable : true
},
fullName : {
get() {
return `${this.fistName} ${this.lastName}`;
},
set(name){
[this.fistName, this.lastName] = name.split(' ');
},
enumerable : true,
configurable : true
}
});
'javascript' 카테고리의 다른 글
Prototype (0) | 2024.06.30 |
---|---|
일급 객체 (0) | 2024.06.29 |
객체 변경 방지 (0) | 2024.06.28 |
Dynamic Scope, Static Scope (0) | 2024.06.26 |
함수 생성시점과 함수 호이스팅 (0) | 2024.06.25 |