본문으로 건너뛰기

프로퍼티 어트리뷰트

작성일 : 2024.10.09

내부 슬롯과 내부 메서드​

  • 내부 슬롯 : 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사야에서 사용하는 의사 프로퍼티 (pseudo property)
  • 내부 메서도 : 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사야에서 사용하는 의사 메서드 (pseudo method)
    • 개발자가 직접 접근할 수 있도록 외부로 공개된 객체의 프로퍼티가 아니다 *

프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체​

  • JS 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동으로 정의한다.
  • Porperty Attribute : [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
  • Object.getOwnPropertyDescriptor 메서드를 사용하여 간접적으로 확인 가능
  • Object.getOwnPropertyDescriptor 메서드는 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크럽터 객체를 반환
  • 존재하지 않는 프로퍼티나 상속받은 프로퍼티에 대한 프로퍼티 디스크럽터를 요구하면 undefined 반환
const person = {
	name: 'Lee'
};
person.age = 20;
console.log(Object.getOwnPropertyDescriptor(person));
/*
{
	name: {value:"Lee", writable: true, enumerable: true, configurable: true},
	age: {value:20, writable: true, enumerable: true, configurable: true}
}
*/
console.log(Object.getOwnPropertyDescriptor(person,'name'));
// {value:"Lee", writable: true, enumerable: true, configurable: true}

데이터 프로퍼티와 접근자 프로퍼티​

  • 데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티
  • 접근자 프로퍼티 : 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티

데이터 프로퍼티​

프로퍼티 어트리뷰트설명
[[Value]]프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값
[[Writable]]프로퍼티 값의 변경 가능 여부
[[Enumerable]]프로퍼티의 열거 가능 여부 for...in, Object.keys 메서드 등으로 열거 가능 여부
[[Configurable]]프로퍼티의 재정의 가능 여부
  • JS 엔진이 프로퍼티를 생성할 때 기본값으로 자동정의한다.

접근자 프로퍼티​

프로퍼티 어트리뷰트설명
[[Get]]접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수
[[Set]]접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
[[Enumerable]]프로퍼티의 열거 가능 여부
[[Configurable]]프로퍼티의 재정의 가능 여부
  • 동작 과정
    1. 프로퍼티 키가 유효한지 확인, 프로퍼티 키는 문자열 또는 심벌이어야 한다.
    2. 프로토타입 체인에서 프로퍼티를 검색
    3. 검색된 프로퍼티가 데이터 프로퍼티인지 접근자 프로퍼티인지 확인ㄴ
    4. 접근자 프로퍼티의 프로퍼티 어트리뷰트 [[Get]]의 값, getter 함수 호출하여 결과를 반환

프로퍼티 정의​

프로퍼티 디스크립터의 프로퍼티생략했을 때의 기본값
valueundefined
getundefined
setundefined
writablefalse
enumerablefalse
configurablefalse
const person = {};
Object.defineProperty(person, 'firstName', {
	value: 'Kee',
	writable: true,
	enumerable: true,
	configurable: true
});
Object.defineProperty(person, 'lastName', {
	value: 'JK'
});
Object.defineProperty(person, 'FullName', {
	get() {
		return `${this.firstName} ${this.lastName}`;
	},
	set(name) {
		[this.firstName, this,lastName] = name.split(' ');
	},
	enumerable: true,
	configurable: true
});
person.fullName = "JK Park";

객체 변경 방지​

구분메서드프로퍼티 추가프로퍼티 삭제프로퍼티 읽기프로퍼티 쓰기프토퍼티 재정의
객체 확장 금지Object.preventExtensionsXOOOO
객체 밀봉Object.sealXXOOX
객체 동결Object.freezeXXOXX
객체 확장 금지​
  • Object.preventExtensions : 객체의 확장을 금지
  • 확장이 금지된 객체는 프로퍼티 추가를 금지된다
const person = {name: 'jk'};
console.log(Object.isExtensiable(person));
Object.preventExtensions(person);
객체 밀봉​
  • Object.seal : 객체를 밀봉
  • 밀봉된 객체는 읽기/쓰기만 가능
const person = {name: 'jk'};
console.log(Object.isSealed(person));
Object.seal(person);
객체 동결​
  • Object.freeze : 객체 동결
  • 동결된 객체는 읽기만 가능
const person = {name: 'jk'};
console.log(Object.isFrozen(person));
Object.freeze(person);
  • 3개의 변경방지 메서드들은 얕은 변경 방지로 직속 프로퍼티만 변경이 방지되고 중첩 객체까지는 영향을 못 준다.
  • 불변 객체를 구현하기 위해선 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드를 호출해야 한다.