const person = { name: 'Lee' }; person.age = 100; console.log(Object.getOwnPropertyDescriptors(person)); /* { name: {value: "Lee", writable: true, enumerable: true, configurable: true} age: {value: 100, writable: true, enumerable: true, configurable: true} } */
const person = { // 데이터 프로퍼티 firstName: "bw", 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); // bw Lee // 접근자 프로퍼티를 통한 프로퍼티 값의 참조 // 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다 person.fullName = "Heegun Lee"; console.log(person); //{firstName: "Heegun", lastName: "Lee"} // 접근자 프로퍼티를 통한 프로퍼티 값의 참조 // 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다. console.log(person.fullName); // Heegun Lee // firstName은 데이터 프로퍼티다 // 데이터 프로퍼티는 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]] 프로퍼티 어트리뷰트를 갖는다 let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName'); console.log(descriptor); // {value: "Lee", writable : true, enumerable : true, configurable: true} // fullName은 접근자 프로퍼티다 // 접근자 프로퍼티는 [[Get]], [[Set]], [[Enumerable]], [[Configurable]] 프로퍼티 어트리뷰트를 갖는다 descriptor = Object.getOwnPropertyDescriptor(person, 'fullName') console.log(descriptor); // {get: f, set: f, enumerable: true, configurable: true}
Object.defineProperty
메서드를 사용하면 프로퍼티의 어트리뷰트를 정의할 수 있다 Enumerable
의 값이 false인 경우, 해당 프로퍼티는 열거할 수 없다Writeable
의 값이 false인 경우, 해당 프로퍼티의 [[Value]]
의 값을 변경할 수 없다Configurable
의 값이 false인 경우, 해당 프로퍼티를 삭제 또는 재정의 할 수 없다const person = {}; // 데이터 프로퍼티 정의 Object.defineProperty(person, 'firstName', { value: 'Ungmo', writable: true, enumerable: true, configurable: true }); // 디스크럽터 객채의 프로퍼티를 누락시키면 undefined, false가 기본값이다 Object.defineProperty(person, 'lastName', { value: 'Lee' })
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
const person = {name: 'Lee'}; // person 객체는 밀봉된 객체가 아니다 console.log(Object.isSealed(person)); // false // person 객체를 밀봉하여 프로퍼티 추가, 삭제, 재정의를 금지한다 Object.seal(person); // person 객체는 밀봉된 객체다 console.log(Object.isSealed(person)); // true // 밀봉된 객체는 configurable이 false이다 console.log(Object.getOwnPropertyDescriptors(person)); /* { name: {value: "Lee", writable: true, enumerable: true, configurable: false}, } */ // 프로퍼티 추가가 금지된다 person.age = 20; // 무시. strict mode에서는 에러 console.log(person); // {name: "Lee"} // 프로퍼티 삭제가 금지된다 delete.person.name; // 무시. strict mode에서는 에러 console.log(person); // {name: "Lee"} // 프로퍼티 값 갱신은 가능하다. person.name = "Kim"; console.log(person); // {name : "Kim"} // 프로퍼티 어트리뷰트 재정의가 금지된다. Object.defineProperty(person, 'name', {configurable : true}); // TypeError: Cannot redefine property: name
const person = {name: 'Lee'}; // person 객체는 동결된 객체가 아니다 console.log(Object.isFrozen(person)); // false // person 객체를 동결하여 프로퍼티 추가, 삭제, 재정의, 쓰기를 금지한다 Object.freeze(person); // person 객체는 동결된 객체다 console.log(Object.isFrozen(person)); // true // 동결된 객체는 writable과 configurable이 false이다 console.log(Object.getOwnPropertyDescriptors(person)); /* { name: {value: "Lee", writable: false, enumerable: true, configurable: false}, } */ // 프로퍼티 추가가 금지된다 person.age = 20; // 무시. strict mode에서는 에러 console.log(person); // {name: "Lee"} // 프로퍼티 삭제가 금지된다 delete.person.name; // 무시. strict mode에서는 에러 console.log(person); // {name: "Lee"} // 프로퍼티 값 갱신은 가능하다. person.name = "Kim"; console.log(person); // {name : "Kim"} // 프로퍼티 어트리뷰트 재정의가 금지된다. Object.defineProperty(person, 'name', {configurable : true}); // TypeError: Cannot redefine property: name