[Javascript] 프로퍼티 어트리뷰트
- -
🍉 1. 내부 슬롯과 내부 매서드
- 프로퍼티 어트리뷰트를 이해하기 위한 개념
- 내부 슬롯과 내부 메서드는 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티(pseudo property)와 의사 메서드(pseudo method)다.
- 자바스크립트 엔진에서 실제로 동작하지만, 외부로 공개된 객체의 프로퍼티는 아니다. -> 직접 접근할 수 없음
🍉 2. 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
자바스크립트 엔진은 프로퍼티를 생성할 때, 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다.
프로퍼티 상태
: 프로퍼티의 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)
프로퍼티 어트리뷰트
: 내부 상태 값인 내부 슬롯 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
-> 프로퍼티 어트리뷰트에 직접 접근 X
-> Object.getOwnPropertyDescriptor 메서드 사용하여 간접적 확인 O
const person = {
name: 'Lee'
};
// 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환한다.
console.log(Object.getOwnPropertyDescriptor(person, 'name'));
// {value: "Lee", writable: true, enumerable: true, configurable: true}
//Object.getOwnPropertyDescriptor 메서드를 호출할 때
//첫 번째 매개변수=> 객체의 참조 전달
//두 번째 매개변수=> 프로퍼티 키를 문자열로 전달
//프로퍼티 디스트립터 객체(프로퍼티 어트리뷰트 정보 제공) 반환
🍉 3. 데이터 프로퍼티와 접근자 프로퍼티
프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.
1) 데이터 프로퍼티
키와 값으로 구성된 일반적인 프로퍼티이다
다음과 같은 프로퍼티 어트리뷰트를 갖는다. 이 프로퍼티 어트리뷰트는 자바스크립트 엔진이 프로퍼티를 생성할 때 기본값으로 자동 정의된다.
프로퍼티 어트리뷰트 | 프로퍼티 디스크립터 객체의 프로퍼티 | 설명 |
[[Value]] | value | 1. 프로퍼티 키를 통해 값에 접근하면 반환되는 값. 2. 프로퍼티 키를 통해 프로퍼티 값을 변경하면 [[Value]]에 값을 재할당. / 이때 프로퍼티 없으면 동적 생성하여 저장 |
[[Writable]] | writable | 1. 프로퍼티 값의 변경 가능 여부 - 불리언 값을 가짐 2. [[Writable]]의 값이 false인 경우, 읽기 전용 프로퍼티가 됨 |
[[Enumerable]] | enumerable | 1. 프로퍼티의 열거 가능 여부 - 불리언 값 2. [[Enumerable]]의 값이 false 인 경우, for...in문이나 Object.keys 메서드 등으로 열거 불가 |
[[Configurable]] | configurable | 1. 프로퍼티 재정의 가능 여부 - 불리언 값 2. [[Configurable]]의 값이 false 인 경우, 삭제, 값의 변경 금지 단, [[Writable]]이 true인 경우, [[Valule]]의 변경과 [[Writable]]을 false로 변경 허용 |
const person = {
name: 'Lee'
};
person.age = 20; //프로퍼티 동적 생성
console.log(Object.getOwnPropertyDescriptor(person));
/* {value: "Lee", writable: true, enumerable: true, configurable: true}
{value: "20", writable: true, enumerable: true, configurable: true}
*/
2) 접근 프로퍼티
자체적으로는 값을 갖지 않고, 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
다음과 같은 프로퍼티 어트리뷰트를 갖는다.
프로퍼티 어트리뷰트 | 프로퍼티 디스크립터 객체의 프로퍼티 | 설명 |
[[Get]] | get | 1. 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수 2. [[Get]]의 값, 즉 getter 함수 호출 -> 프로퍼티 값으로 변환 |
[[Set]] | set | 1. 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수 2. [[Set]]의 값, 즉 setter 함수 호출 -> 프로퍼티 값으로 저장 |
[[Enumerable]] | enumerable | 데이터 프로퍼티의 [[Enumerable]]과 같다 |
[[Configurable]] | configurable | 데이터 프로퍼티의 [[Configurable]]과 같다 |
접근자 함수는 getter/setter 함수라고도 부른다.
🍉 4. 프로퍼티 정의
프로퍼티 정의란 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말한다.
Object.defineProperty 메서를 사용하면 프로퍼티의 어트리뷰트를 정의할 수 있다.
인수로는 객체의 참조, 데이터 프로퍼티의 키(문자열), 프로퍼티 디스크립터 객체를 전달한다.
const person = {};
// 데이터 프로퍼티 정의
Object.defineProperty(person, 'firstName', {
value: 'Ungmo',
writable: true,
enumerable: true,
configurable: true
});
Object.defineProperty(person, 'lastname', {
value:'Lee'
});
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log('firstName', descriptor);
// firstName {value: "Ungmo", writable: true, enumerable: true, configurable: true}
- Object.defineProperty 메서드는 한번에 하나의 프로퍼티만 정의할 수 있다.
- Object.defineProperties 메서드를 사용하면 여러 개의 프로퍼티를 한 번에 정의할 수 있다.
🍉 5. 객체 변경 방지
객체는 변경 가능한 값이므로 재할당 없이 직접 변경할 수 있다.
ex) 프로퍼트 추가,삭제,갱신
ex) 프로퍼티 어트리뷰트 재정의 ( Object.defineProperty, Object.defineProperties 사용)
따라서 자바스크립트는 객체의 변경을 방지하는 다양한 메서드를 제공한다.
간단히 표로 정리하면 다음과 같다.
구분 | 메서드 | 프로퍼티 추가 |
프로퍼티 삭제 | 프로퍼티 값 읽기 |
프로퍼티 값 쓰기 |
프로퍼티 어트리뷰트 재정의 |
객체 확장 금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
위 내용을 자세히 살펴보자.
1. 객체 확장 금지(Object.preventExtensions)
Object.preventExtensions 메소드는 객체에 새로운 프로퍼티를 추가할 수 없도록 설정한다. 하지만, 이미 존재하는 프로퍼티의 값은 변경할 수 있다. 이 때, [[Extensible]] 프로퍼티가 false로 변경된다.
let person = { name: 'Sumin', age: 20 };
Object.preventExtensions(person);
person.gender = 'Male'; // 프로퍼티 추가 무시됨 (strict mode에서는 TypeError 발생)
console.log(person); // { name: 'Sumin', age: 20 }
console.log(Object.isExtensible(person)); // false
2. 객체 밀봉(Object.seal)
Object.seal 메소드는 다음을 금지하며, 이를 객체 밀봉이라 한다.
- 프로퍼티 추가 금지
- 프로퍼티 삭제 금지
- 프로퍼티 어트리뷰트 재정의 금지
밀봉된 객체는 읽기와 쓰기만 가능하다.
let person = { name: 'Sumin', age: 20 };
Object.seal(person);
delete person.age; // 프로퍼티 삭제 무시됨 (strict mode에서는 TypeError 발생)
person.gender = 'Male'; // 프로퍼티 추가 무시됨 (strict mode에서는 TypeError 발생)
person.name = 'Mike'; // 프로퍼티 값 갱신은 가능
Object.defineProperty(person,'name',{configurableL:true}); // 프로퍼티 어어트리뷰트 재정의 금지
console.log(person); // { name: 'Mike', age: 30 }
console.log(Object.isSealed(person)); // true
3. 객체 동결(Object.freeze)
Object.freeze 메소드는 다음을 금지하며, 이를 객체 동결이라 한다.
- 프로퍼티 추가 금지
- 프로퍼티 삭제 금지
- 프로퍼티 어트리뷰트 재정의 금지
- 프로퍼티 값 갱신 금지
동결된 객체는 읽기만 가능하다.
let person = { name: 'Sumin', age: 20 };
Object.freeze(person); //객체 동결
delete person.age; // 무시됨 (strict mode에서는 TypeError 발생)
person.gender = 'Male'; // 무시됨 (strict mode에서는 TypeError 발생)
person.name = 'Mike'; // 무시됨 (strict mode에서는 TypeError 발생)
console.log(person); // { name: 'Sumin', age: 20 }
console.log(Object.isFrozen(person)); // true
4. 불변객체(Immutable Object)
불변객체(Immutable Object)는 객체 생성 후 객체의 상태를 변경할 수 없는 객체로 이러한 객체는 생성 이후에는 추가, 삭제, 수정이 불가능하며, 객체 내부의 프로퍼티들도 불변한다. 대신, 객체를 변경하는 대신에 새로운 객체를 생성하거나 복사해서 원하는 상태를 만들 수 있다.
Reference
https://ganxdev.tistory.com/83
[지금 무료] 모던 자바스크립트 딥다이브 스터디 강의 | 정재남 - 인프런
정재남 | 《모던 자바스크립트 딥다이브》 책 내용을 그대로 따라가는 스터디 영상입니다. 함께 공부하면 훨씬 쉬워질 거에요!, 혼자가 외롭다면 시간차 스터디는 어때요?함께하는 모던 자바스
www.inflearn.com
https://msj725.tistory.com/159
[자바스크립트] 프로퍼티 어트리뷰트(Property Attribute)
본 내용은 이웅모 님의 모던 "자바스크립트 DeepDive" 책을 보고 정리한 내용입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다. 내부슬롯과 내부 메서드 - 내부슬롯과 내부 메서드는 JavaScrip
msj725.tistory.com
소중한 공감 감사합니다