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

HustleKang·2022년 4월 4일

내부 슬롯과 내부 메서드

자바스크립트 엔진의 내부 로직, 원칙적으로 직접 접근과 호출이 불가
일부만 간접적으로 접근할 수 있는 수단이 제공됨

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

자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티 어트리뷰트를 자동 정의함
프로퍼티 어트리뷰트 : 프로퍼티의 상태를 나타냄
프로퍼티 어트리뷰트는 내부 슬롯이다 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
즉 직접 접근이 불가
Object.getOwnPropertyDescriptor 메서드로 간접적 확인 가능
Object.getOwnPropertyDescriptor는 프로퍼티 디스크립터 객체를 반환

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

데이터 프로퍼티 : 일반적인 키,값으로 구성된 프로퍼티
접근자 프로퍼티 : 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수(getter,setter)로 구성된 프로퍼티, 값은 따로 없음

데이터 프로퍼티

  • 데이터 프로퍼티의 프로퍼티 어트리뷰트
    • [[Value]]
    • [[Writable]] : 값 변경 가능 여부
    • [[Enumerable]] : 열거 가능 여부 , false면 Object.keys에서 제외
    • [[Configurable]] : 재정의 가능 여부, false면 프로퍼티 삭제불가, 프로퍼티 어트리뷰트 변경 불가, [[Writable]]이 true면 [[Value]]와 [[Writable]] 변경은 가능

접근자 프로퍼티

  • 접근자 프로퍼티의 프로퍼티 어트리뷰트
    • [[Get]] : 접근자 프로퍼티로 데이터 프로퍼티의 값을 읽을 때 호출,getter함수의 결과값을 반환
    • [[Set]] : 접근자 프로퍼티로 값을 저장할 때 호출,setter함수의 결과가 저장됨
    • [[Enumerable]]
    • [[Configurable]]
const person = {
	// 데이터 프로퍼티
	firstName:'Hustle',
	lastName:'Kang',
	
    //fullName은 접근자 프로퍼티
	get fullName(){
		return `${this.firstName} ${this.lastName}`;
        },
    
    set fullName(name){
    	[this.firstName,this,lastName] = name.split(' ');
        }
   };
   
console.log(person.fullName); // Hustle Kang
person.fullname = 'Adam Smith'; //접근자 프로퍼티에 값 할당 시 setter함수 실행

프로퍼티 정의

프로퍼티의 프로퍼티 어트리뷰트를 명시적으로 정의한다
Object.defineProperty,Object.defineProperties 메서드로 정의

const person = {};

// 데이터 프로퍼티 정의
Object.defineProperty(person,'firstName',{
	value : 'Hustle', // 기입 안하면 undefined
	writable : true, // 기입 안하면 false
	enumerable : true, // 기입 안하면 false
	configurable : true // 기입 안하면 false
});

// 접근자 프로퍼티 정의
Object.defineProperty(person,'fullName',{
	get() {
		return `${this.firstName} ${this.lastName}`;
    },
    set(name) {
    	[this.firstName,this,lastName] = name.split(' ');
    },
    enumerable : true,
    configurable : true
});

객체 변경 방지

객체는 프로퍼티 추가,삭제,값 읽기,값 쓰기와 프로퍼티 어트리뷰트의 재정의가 가능

  • 객체 확장 금지

    프로퍼티 추가가 불가능해짐
    Object.isExtensible(객체); // true,false
    Object.preventExtensions(객체); // 프로퍼티 추가가 불가능해짐
  • 객체 밀봉

    읽기,쓰기만 가능
    [[Configurable]]이 false
    Object.isSealed(객체); // true,false
    Object.seal(객체); 밀봉시킴
  • 객체 동결

    읽기만 가능
    [[Configurable]], [[Writable]]이 false
    Object.isFrozen(객체); // true,false
    Object.freeze(객체); 동결시킴

불변 객체

위 3가지는 얕은 변경 방지이다.
직속 프로퍼티 변경만 방지되고 중첩된 객체는 변경이 가능함

const person = {
	address : {country : 'Korea', city : 'Seoul'}
    };   
   
Object.freeze(person);
person.address.city = 'Jeju'; // 변경 됨 

이웅모, 『모던 자바스크립트 Deep Dive』, 위키북스(2021)

profile
grindin'

0개의 댓글