속성의 본질적인 속성 설명자
JavaScript의 객체는 다음과 같이 <key> : <value> 쌍으로 이루어진 존재입니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
name이라는 key는 'Kang JaeSeong' value와 매핑되며, age라는 key는 30이라는 value와 매핑됩니다.
Object.getOwnPropertyDescriptor()
함수를 사용하면, 객체의 속성에 대한 모든 설명을 확인할 수 있습니다. 다음은 userInfo 객체의 name 속성에 대한 설명자입니다.
console.log(Object.getOwnPropertyDescriptor(userInfo, 'name'));
실행 결과
속성 설명자에 value, writable, enumerable 및 configurable 네 가지 설명자가 존재하며, value를 제외한 속성의 값은 기본적으로 true입니다.
만약, userInfo 객체에 존재하지 않는 속성에 대한 설명자를 확인하는 경우 Object.getOwnPropertyDescriptor()
함수는 undefined를 반환합니다.
console.log(Object.getOwnPropertyDescriptor(userInfo, 'highSchool'));
실행 결과
writable
writable 속성은 해당 속성의 값을 변경할 수 있는지 여부를 나타냅니다. Object.defineProperty()
함수는 설명자에 존재하는 속성의 값을 설정할 수 있습니다.
다음은 Object.defineProperty()
함수로 설명자의 writable 속성 값을 false로 변경합니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {writable: false});
console.log(Object.getOwnPropertyDescriptor(userInfo, 'name'));
실행 결과
userInfo객체의 name 속성의 설명자 writable 속성 값을 false로 변경 후 name 속성의 값을 변경하면 적용되지 않습니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {writable: false});
userInfo.name = 'Kim JaeSeong';
console.log(userInfo);
실행 결과
그러나 다음과 같이 중첩된 객체인 경우(속성이 객체인 경우)에는 writable의 속성을 false로 설정해도 값이 변경되는 문제가 존재합니다.
const userInfo = {
name: {
firstName: 'Kang',
lastName: 'JaeSeong'
},
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {writable: false});
userInfo.name.firstName = 'Kim';
console.log(userInfo);
실행 결과
객체는 값을 가지는 형식(Call by value)이 아니라 값을 참조하는 형식(Call by reference)이므로 중첩된 객체의 속성을 변경하는 것을 막지 않습니다.
만약, userInfo.name
객체 속성의 값 변경, 속성 추가, 속성 제거를 방지하고 싶은 경우 Object.freeze()
함수를 사용합니다.
Object.freeze(userInfo.name);
다음은 Object.freeze()
함수 호출 후 userInfo.name.firstName
의 값을 변경하는 예제입니다.
const userInfo = {
name: {
firstName: 'Kang',
lastName: 'JaeSeong'
},
age: 30,
address: 'Busan'
}
Object.freeze(userInfo.name);
userInfo.name.firstName = 'Kim';
console.log(userInfo);
실행 결과
enumerable
기본적으로 객체의 속성은 열거(enumerable) 가능하므로 for...in
반복문으로 접근할 수 있습니다. 그러나 enumerable 속성을 false로 설정하면 객체의 속성을 열거할 수 없습니다.
다음은 enumerable 속성이 true일 때, for...in
반복문으로 객체의 속성을 접근하는 예제입니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
console.log(Object.getOwnPropertyDescriptor(userInfo, 'name').enumerable);
for (const key in userInfo) {
console.log(`key : ${key}`);
}
실행 결과
다음은 userInfo.name
속성의 enumerable을 false로 변경 후 for...in
반복문으로 객체의 속성을 접근하는 예제입니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {enumerable: false});
console.log(Object.getOwnPropertyDescriptor(userInfo, 'name').enumerable);
for (const key in userInfo) {
console.log(`key : ${key}`);
}
configurable
configurable 속성은 false로 설정되면 해당 속성을 잠그고 enumerable 및 configurable을 다시 변경하는 것을 방지합니다. 그리고 해당 속성을 삭제하지 못하도록 방지합니다. 하지만 쓰기(writable)는 가능합니다.
다음은 configurable 속성을 false로 변경 후 enumerable 속성을 false로 변경하는 예제입니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {configurable: false});
console.log(Object.getOwnPropertyDescriptor(userInfo, 'name'));
Object.defineProperty(userInfo, 'name', {enumerable: false});
실행 결과
마찬가지로 configurable 속성을 다시 true로 변경하는 경우 TypeError가 발생합니다.
다음은 configurable 속성이 false인 경우 delete
키워드로 속성을 제거하는 예제입니다.
const userInfo = {
name: 'Kang JaeSeong',
age: 30,
address: 'Busan'
}
Object.defineProperty(userInfo, 'name', {configurable: false});
delete userInfo.name;
console.log(userInfo);
실행 결과
위에서 언급했듯이 configurable이 false인 속성은 제거되지 않습니다.
'JavaScript > 객체' 카테고리의 다른 글
[JavaScript]동적으로 프로퍼티 추가 (0) | 2022.06.24 |
---|---|
[JavaScript]Map 객체 정렬하는 방법 (0) | 2022.01.03 |
[JavaScript]프로토타입(Prototype)이란? (0) | 2021.12.27 |
[JavaScript]Date 객체 유효성 체크 (0) | 2021.12.23 |
[JavaScript]Date와 new Date 차이점 (0) | 2021.12.22 |
댓글