[JavaScript] 딥다이브 / 16장 프로퍼티 어트리뷰트

ungnam·2023년 6월 20일
0
post-thumbnail

내부 슬롯과 내부 메서드

내부 슬롯내부 메서드는 JS 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티와 의사 메서드로, 이중 대괄호([[..]])로 감싼 이름들이 여기에 해당한다.

내부 슬롯과 메서드는 개발자가 직접 접근할 수는 없지만, 모든 객체가 가지고 있는 [[Prototype]] 내부 슬롯의 경우, 예외적으로 __proto__를 통해 간접적으로 접근할 수 있다.

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

프로퍼티 생성 시 JS 엔진이 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의함

프로퍼티 어트리뷰트는 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]] 내부 슬롯으로 이루어져 있는데, Object.getOwnPropertyDescriptor(s) 메서드를 사용하여 반환되는 프로퍼티 디스크럽터 객체를 통해 프로퍼티 어트리뷰트 정보를 간접적으로 확인할 수 있다.

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

데이터 프로퍼티

프로퍼티 어트리뷰트프로퍼티 디스크립터 객체의 프로퍼티설명
[[Value]]value프로퍼티 키를 통해 프로퍼티 값에 접근 시 반환되는 값
[[Writable]]writable값의 변경 가능 여부를 나타내며 false인 경우 해당 프로퍼티는 읽기 전용 프로퍼티가 된다.
[[Enumerable]]eumerable값의 열거 가능 여부를 나타내며 false인 경우 for...in문이나 Object.keys 메서드 등으로 열거할 수 없다.
[[Configurable]]configurable프로퍼티 재정의 가능 여부를 나타내며 false인 경우 프로퍼티 삭제 및 프로퍼티 어트리뷰트 값의 변경이 금지된다.
단, [[Writable]]true인 경우 값 변경 및 [[Writable]]false로 변경하는 것은 허용된다.

접근자 프로퍼티

프로퍼티 어트리뷰트프로퍼티 디스크립터 객체의 프로퍼티설명
[[Get]]get접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수
[[Set]]set접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
[[Enumerable]]enumerable데이터 프로퍼티의 [[Enumerable]]과 동일
[[Configurable]]configurable데이터 프로퍼티의 [[Configurable]]과 동일
const person = {
  // 데이터 프로퍼티
  firstName: 'mono',
  lastName: 'kuma',
  
  // 접근자 프로퍼티
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  set fullName(name) {
    [this.firstName, this.lastName] = name.split(' ');
  }
};

// 데이터 프로퍼티를 통한 프로퍼티 값의 참조 / [[Value]]의 값이 반환
console.log(person.firstName + ' ' + person.lastName);

// 접근자 프로퍼티를 통한 프로퍼티 값의 저장 / [[Set]]의 값인 setter 함수 호출
person.fullName = 'shiro kuma';

// 접근자 프로퍼티를 통한 프로퍼티 값의 참조 / [[Get]]의 값인 getter 함수 호출
console.log(person.fullName);

// {value: 'shiro', writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(person, 'firstName'));
// {get: f, set: f, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(person, 'fullName'));

프로퍼티 정의

새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의 및 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것

Object.definePropert[y|ies] 메서드를 사용하며, 프로퍼티 디스크럽터 객체에서 생략된 어트리뷰트는 undefined(value, get, set의 경우) 또는 false(writable, enumerable, configurable) 기본값이 적용된다.

객체 변경 방지

객체 확장 금지 : Object.preventExtensions

프로퍼티 동적 추가 및 Object.defineProperty를 통한 프로퍼티 추가가 금지됨 -> Object.isExtensible로 확장 가능한 객체인지 여부 확인 가능

객체 밀봉 : Object.seal

프로퍼티 추가 및 삭제, 프로퍼티 어트리뷰트 수정이 금지됨, 즉 읽기쓰기(값 갱신)만 가능 -> Object.isSealed로 밀봉된 객체인지 여부 확인 가능

객체 동결 : Object.freeze

프로퍼티 값 갱신도 불가능하며, 오로지 읽기만 가능 -> Object.isFrozen으로 동결된 객체인지 여부 확인 가능

불변 객체
지금까지 살펴본 변경 메서드는 중첩 객체까지 영향을 주지 못함 -> 불변 객체를 만들기 위해서는 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드를 호출해야 함

profile
꾸준함을 잃지 말자.

0개의 댓글