🌟 Property attribute 와 Property descriptor.
자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 Property Attribute
를 기본값으로 자동 정의한다.
const person = {
name: "Lee",
};
console.log(Object.getOwnPropertyDescriptor(person, "name"));
// {value: 'Lee', writable: true, enumerable: true, configurable: true}
const person = {
name: "Lee",
};
console.log(Object.getOwnPropertyDescriptor(person, "name"));
// {value: 'Lee', writable: true, enumerable: true, configurable: true}
프로퍼티의 상태
란 프로퍼티의 값(value), 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)을 말한다.
Property attribute
는 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯이다. 따라서, 직접 접근할 수 없지만, Object.getOwnPropertyDescriptor 메서드를 사용해 간접적으로 확인할 수 있다.
🌟 Data property 와 Accesor property
프로퍼티는 데이터 프로퍼티(data property)
와 접근자 프로퍼티(accesor property)
로 구분할 수 있다
데이터 프로퍼티는 키와 값으로 구성된 일반적인 프로퍼티이다. (위에서 살펴본 value, writable, enumerable, configurable 이 데이터 프로퍼티의 프로퍼티 어트리뷰트이다)
접근자 프로퍼티는 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티다.
접근자 프로퍼티는 다음과 같은 프로퍼티 어트리뷰트를 갖는다.
- [[Get]] : 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수다.
- [[Set]] : 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수다.
- [[Enumerable]]
- [[Configurable]]
접근자 함수는getter/setter
함수라고도 부른다.
const person = {
firstName: "Ungmo",
lastName: "Lee",
//getter함수
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
//setter함수
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
},
};
//데이터 프로퍼티를 통한 값의 참조
console.log(person.firstName + " " + person.lastName); // Ungmo Lee
//접근자 프로퍼티를 통한 값의 저장, setter함수 호출
person.fullName = "Heegun Lee";
console.log(person); // {firstName: 'Heegun', lastName: 'Lee'}
console.log(person.fullName); // Heegun Lee
let descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
console.log(descriptor);
// {value: 'Heegun', writable: true, enumerable: true, configurable: true}
descriptor = Object.getOwnPropertyDescriptor(person, "fullName");
console.log(descriptor);
//fullName은 접근자 프로퍼티이기 때문에, 아래의 프로퍼티 어트리뷰트를 갖는다
// {enumerable: true, configurable: true, get: ƒ, set: ƒ}
const person = {
firstName: "Ungmo",
lastName: "Lee",
//getter함수
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
//setter함수
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
},
};
//데이터 프로퍼티를 통한 값의 참조
console.log(person.firstName + " " + person.lastName); // Ungmo Lee
//접근자 프로퍼티를 통한 값의 저장, setter함수 호출
person.fullName = "Heegun Lee";
console.log(person); // {firstName: 'Heegun', lastName: 'Lee'}
console.log(person.fullName); // Heegun Lee
let descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
console.log(descriptor);
// {value: 'Heegun', writable: true, enumerable: true, configurable: true}
descriptor = Object.getOwnPropertyDescriptor(person, "fullName");
console.log(descriptor);
//fullName은 접근자 프로퍼티이기 때문에, 아래의 프로퍼티 어트리뷰트를 갖는다
// {enumerable: true, configurable: true, get: ƒ, set: ƒ}
메서드 앞에 get
, set
이 붙은 메서드가 있는데, 이것들이 바로 getter
와 setter
함수이고, getter/setter
함수의 이름 fullName
이 접근자 프로퍼티이다.
접근자 프로퍼티는 자체적으로 값(value)를 갖지 않고 데이터 프로퍼티의 값을 읽거나 저장할 때 관여할 뿐이다.
🌟 프로퍼티 정의
프로퍼티 정의
란 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하건, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다.
const person = {};
// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName',{
value : "ungmo",
writable : true,
enumerable : true,
configurable : true,
}
// 접근자 프로퍼티 정의
Object.defineProperty(person, 'fullName',{
get(){
return `${this.firstName} ${this.lastName}`
},
set(name){
[this.firstName,this.lastName] = name.split(' ');
},
enumerable : true,
configurable : ture
}
const person = {};
// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName',{
value : "ungmo",
writable : true,
enumerable : true,
configurable : true,
}
// 접근자 프로퍼티 정의
Object.defineProperty(person, 'fullName',{
get(){
return `${this.firstName} ${this.lastName}`
},
set(name){
[this.firstName,this.lastName] = name.split(' ');
},
enumerable : true,
configurable : ture
}
🌟 객체 변경 방지
자바스크립트 객체는 변경 가능한 값이므로, 직접 변경할 수 있다. 이를 방지하는 다양한 메서드 또한 존재한다.
객체 확장 금지
Object.preventExtensions
메서드는 객체의 확장을 금지한다. 확장이 금지된 객체는 프로퍼티 추가가 금지된다.
const person = { name: "Lee" };
Object.preventExtensions(person);
person.age = 20;
// 프로퍼티 추가가 금지된다.
// strict mode에서는 에러발생
delete person.name;
// 프로퍼티 삭제는 가능
const person = { name: "Lee" };
Object.preventExtensions(person);
person.age = 20;
// 프로퍼티 추가가 금지된다.
// strict mode에서는 에러발생
delete person.name;
// 프로퍼티 삭제는 가능
객체 밀봉
Object.seal
메서드는 객체를 밀봉한다. 밀봉된 객체는 읽기와 쓰기만 가능하다.
const person = { name: "Lee" };
Object.seal(person);
person.age = 20; //금지
delete person.name; //삭제 또한 금지
person.name = "Kim"; //값 갱신은 가능
const person = { name: "Lee" };
Object.seal(person);
person.age = 20; //금지
delete person.name; //삭제 또한 금지
person.name = "Kim"; //값 갱신은 가능
객체 동결
Object.freeze
메서드는 객체를 동결한다. 동결된 객체는 읽기만 가능하다.
const person = { name: "Lee" };
Object.seal(person);
person.age = 20; //금지
delete person.name; //삭제 또한 금지
person.name = "Kim"; //갱신 또한 불가
const person = { name: "Lee" };
Object.seal(person);
person.age = 20; //금지
delete person.name; //삭제 또한 금지
person.name = "Kim"; //갱신 또한 불가