모던 자바스크립트 Deep Dive - 16장 프로퍼티 어트리뷰트

송히·2023년 10월 20일
0
post-thumbnail

16.1 내부 슬롯과 내부 메서드

  • 내부 슬롯 / 내부 메서드: 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티 / 의사 메서드, 이중 대괄호로 감싼 이름들에 해당
const o = {};
// 내부 슬롯은 자바스크립트 엔진의 내부 로직이라 직접 접근 불가
o.[[Prototype]] // Unexpected token '['

// 일부 내부 슬롯과 내부 메서드에 한해 간접적으로 접근할 수 있는 수단 제공
o.__proto__ // Object.prototype

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

자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의함

프로퍼티 상태프로퍼티 어트리뷰트
프로퍼티의 값[[value]]
값의 갱신 가능 여부[[Writable]]
열거 가능 여부[[Enumerable]]
재정의 가능 여부[[Configurable]]
  • Object. getOwnPropertyDescriptor 메서드: 첫 번째 매개변수(객체의 참조를 전달), 두 번째 매개변수(프로퍼티 키를 문자열로 전달)
    => 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체를 반환 (존재하지 않으면 undifined 반환)
    => ES8에서 도입된 버전은 모든 프로퍼티의 프로퍼티 어트리뷰트
    정보를 제공하는 프로퍼티 디스크립터 객체들을 반환함
const person = { 
name: 'Lee' 
} : 
// 프로퍼티 어트리뷰트 정보를 제공히는 프로퍼티 디스크립터 객체 반환 
console.log(object.getownPropertyDescriptor(person, 'name')); 
// {value·. "Lee", writable: true, enumerable: true, configurable: true}

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

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

16.3.1 데이터 프로퍼티

자바스크립트 엔진이 프로퍼티를 생성할 때 기본값으로 자동 정의됨

  • 데이터 프로퍼티의 프로퍼티 어트리뷰트

16.3.2 접근자 프로퍼티

  • 접근자 프로퍼티의 프로퍼티 어트리뷰트

const person = { // 데이터 프로퍼티 
	firstName: 'songhee' , 
	lastName: 'Ha' , 
  
	get fullName() { // 접근자 프로퍼티, getter 함수
	return `${this.firstName} ${this.lastName}`; 
},
set fullName(name) { // setter 함수 
	[this.firstName, this.lastName] = name.split( ' '); 
	} 
};

// 데이터 프로퍼티를 통한 프로퍼티 값의 참조. 
console.log(person.firstName + , ' ' + person.lastName); // Ha songhee

// 접근자 프로퍼티를 통한 프로퍼티 값의 참조 -> setter 함수 호출
person.fullName = 'Ha songhee'; // 접근자 프로퍼티를 통한 값의 참조
console.log(person); // {firstName: "Ha", lastName: "songhee"}
// 접근자 프로퍼티를 통한 값의 참조 -> getter 함수 호출 
console.log(person.fullName); // Ha songhee 

// firstName은 데이터 프로퍼티
console.log(Object.getOwnPropertyDescriptor(person, 'firstName')) // {value: 'Ha', writable: true, enumerable: true, configurable: true}

// fullName은 접근자 프로퍼티
console.log(Object.getOwnPropertyDescriptor(person, 'fullName')) // {get: ƒ, set: ƒ, enumerable: true, configurable: true}
  • 접근자 프로퍼티와 데이터 프로퍼티를 구별하는 방법
    => Object .getOwnPropertyDescriptor 메서드의 객체 프로퍼티가 다름
// 일반 객체의 __proto__는 접근자 프로퍼티 
Object.getOwnPropertyDescriptor(Object.prototype, '__proto_ _' ); 
// {get: f, set: f, enumerable: false, configurable: true} 

// 함수 객체의 prototype은 데이터 프로퍼티 
object.getownPropertyDescriptor(function() {}, 'prototype ' ); 
// {value: {...}, writable: true, enumerable: false, configurable: false}

16.4 프로퍼티 정의

새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나, 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의 하는 것
-> 객체의 프로퍼티가 어떻게 동작해야 하는지를 명확히 정의 가능

  • Object.defineProperty 메서드: 프로퍼티의 어트리뷰트를 정의 가능, 인수로 객체의 참조와 데이터 프로퍼티의 키인 문자열, 프로퍼티 디스크립터 객체 전달
    -> 프로퍼티 디스크립터 객쳬의 프로퍼티를 일부 생략 가능, 한번에 하나의 프로퍼티만 정의 가능
    ㅤ=> 한 번에 여러 개 프로퍼티 정의 원하면 Object.defineProperties 메서드 사용

  • 프로퍼티 디스크립터 객쳬에서 생략된 어트리뷰트의 기본값

16.5 객체 변경 방지

객체는 변경 가능한 값이므로 재할당 없이 직접 변경 가능
-> 프로퍼티를 추가, 삭제, 값 갱신, Object.defineProperty( / defineProperties) 메서드로 어트리뷰트를 재정의

  • 객체 변경 방지 메서드 종류

16.5.1 객체 확장 금지

  • Object.preventExtensions 메서드: 객쳬 확장 금지 메서드, 확장이 금지된 객체는 프로퍼티 추가가 금지됨
  • Object.isExtensible 메서드: 확장 가능 객체 여부 확인

16.5.2 객체 밀봉

  • Object.seal 메서드: 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지 -> 읽기, 쓰기만 가능
  • Object.isSealed 메서드: 밀본된 객체 여부 확인

16.5.3 객체 동결

  • Object.freeze 메서드: 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지, 프로퍼티 값 갱신 금지 -> 읽기만 가능
  • Object.isFrozen 메서드: 동결된 객체 여부 확인

16.5.4 불변 객체

위 3가지 변경 방지 메서드들은 얕은 변경 방지로 직속 프로퍼티만 변경이 방지됨 -> 중첩 객체까지 영향 못 미침

  • 불변 객체: 객쳬의 중첩 객쳬까지 동결하여 변경이 불가능한 읽기 전용
    => 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 Object.freeze 메서드 호출
    => 깊은 객체 동결
profile
데브코스 프론트엔드 5기

0개의 댓글