📌 프로퍼티에 대해서 정확히 이해하기는 어려웠지만 이번 장을 공부하면서 많이 이해할 수 있었다. 객체를 더 많이 다루고 사용하기 위해선 꼭 이해가 필요했던 장이었다.
자바스크립트 엔징늬 구현알고리즘을 설명하기 위해 EMCAScript 사양에서 사용하는
의사프로퍼티
와의사매서드
다.EMCAScript 사양에 등장하는 이중 대괄호로 감싼 이름들이 내부슬롯과 내부매서드다
자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동정의한다.
Object.getOwnPropertyDescriptor 매서드를 이용해 간접적으로 확인가능
const person = {
name: 'Lee'
};
// 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다.
console.log(Object.getOwnPropertyDescriptor(person, 'name'));
// {value: "Lee", writable: true, enumerable: true, configurable: true}
접근자란?
객체지향 프로그래밍에서 객체가 가진 프로퍼티 값을 객체 바깥에서 읽거나 쓸 수 있도록 제공하는 매서드
let obj = {
get propName(){
//getter, obj.propName을 실행할 때 실행되는 코드
}
set propName(value){
// setter, obj.propName = value를 실행할 때 실행되는 코드
}
데이터 프로퍼티와 접근자 프로퍼티를 구분하는 쉬운예시
const person = {
// 데이터 프로퍼티
firstName: 'Ungmo',
lastName: 'Lee',
// fullName은 접근자 함수로 구성된 접근자 프로퍼티다.
// getter 함수
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
// setter 함수
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
};
어떤 객체의 상위(부모)객체의 역할을 하는 객체다. 프로토타입은 하위 객체에게 자신의 프로퍼티와 매서드를 상속한다. 프로토타입 객체의 프로퍼티를 상속받은 하위 객체는 자신의 프로퍼티 또는 매서드인 것처럼 자유롭게 사용할 수 있다.
Object.defineProperty 매서드를 통해 열거, 재정의, 갱신가능여부(프로퍼티 어트리뷰트)를 재정의하는 것
(Object.definedProperties는 여러개의 프로퍼티를 한번에 정의가능)
기본값은 undefined, false이다.
const person = {};
// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName', {
value: 'Ungmo',
writable: true,
enumerable: true,
configurable: true
});
1. 객체 확장금지
- Object.preventExtensions 매서드를 쓰면 프로퍼티 추가가 금지된다.
const person = { name: 'Lee' };
// person 객체는 확장이 금지된 객체가 아니다.
console.log(Object.isExtensible(person)); // true
// person 객체의 확장을 금지하여 프로퍼티 추가를 금지한다.
Object.preventExtensions(person);
// person 객체는 확장이 금지된 객체다.
console.log(Object.isExtensible(person)); // false
// 프로퍼티 추가가 금지된다.
person.age = 20; // 무시. strict mode에서는 에러
console.log(person); // {name: "Lee"}
// 프로퍼티 추가는 금지되지만 삭제는 가능하다.
delete person.name;
console.log(person); // {}
// 프로퍼티 정의에 의한 프로퍼티 추가도 금지된다.
Object.defineProperty(person, 'age', { value: 20 });
// TypeError: Cannot define property age, object is not extensible
2. 객체 밀봉
- Object.seal 매서드를 쓰면 읽기와 쓰기만 가능, 삭제불가, 갱신은 가능
3. 객체 동결
- Object.freeze. 읽기만 가능, 삭제와 갱신, 추가 금지
이렇게 해도 중첩객체까지는 영향을 못준다. 이럴 땐 불변객체를 구현해야한다.
function deepFreeze(target) {
// 객체가 아니거나 동결된 객체는 무시하고 객체이고 동결되지 않은 객체만 동결한다.
if (target && typeof target === 'object' && !Object.isFrozen(target)) {
Object.freeze(target);
/*
모든 프로퍼티를 순회하며 재귀적으로 동결한다.
Object.keys 메서드는 객체 자신의 열거 가능한 프로퍼티 키를 배열로 반환한다.
("19.15.2. Object.keys/values/entries 메서드" 참고)
forEach 메서드는 배열을 순회하며 배열의 각 요소에 대하여 콜백 함수를 실행한다.
("27.9.2. Array.prototype.forEach" 참고)
*/
Object.keys(target).forEach(key => deepFreeze(target[key]));
}
return target;
}
const person = {
name: 'Lee',
address: { city: 'Seoul' }
};
// 깊은 객체 동결
deepFreeze(person);
console.log(Object.isFrozen(person)); // true
// 중첩 객체까지 동결한다.
console.log(Object.isFrozen(person.address)); // true
person.address.city = 'Busan';
console.log(person); // {name: "Lee", address: {city: "Seoul"}}