[스터디] 프로퍼티 어트리뷰트

김하은·2024년 1월 18일
0

스터디

목록 보기
6/23

주제 선정 이유

프로퍼티 어트리뷰트의 내용은 생소한 내용이어서 복습하기 위해 전체 내용을 요악하기로 함


내부 슬롯과 내부 메서드

자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양에서 사용하는 의사 프로퍼티(pseudo property)와 의사 메서드(pseudo method)임

  • 의사: 개발자에게 직접적으로 노출되지 않지만, 언어의 구현과 동작을 설명하기 위해 도입된 가상적인 또는 추상적인 개념을 나타내는 용어
  • 의사 프로퍼티: 실제로 코드에서 직접적으로 접근할 수 없는 내부 슬롯
  • 의사 메서드: 직접 호출되지 않고 내부적으로 엔진에 의해 사용되는 내부 메서드

예를 들어, 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는데 내부 슬롯은 자바스크립트 엔진의 내부 로직이므로 원칙적으로 직접 접근할 수 없지만 [[Prototype]]내부 슬롯의 경우, __proto__를 통해 간접적으로 접근할 수 있음

const o = {};

o.[[Prototype]] // -> Uncaught SyntaxError: Unexpected token '['
o.__proto__ // -> Object.prototype

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

  • 자바스크립트 엔진은 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의함
  • 프로퍼티 상태:
    • 프로퍼티의 값(value)
    • 값의 갱신 가능 여부(writable)
    • 열거 가능 여부(enumerable)
    • 재정의 가능 여부(configurable)
  • 프로퍼티 어트리뷰트: 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯임
  • 내부 슬롯:
    • [[Value]]: 프로퍼티에 대한 실제 값이 저장되는 내부 슬롯입니다.
    • [[Writable]]: 이 내부 슬롯은 프로퍼티의 값이 변경 가능한지 여부를 나타냅니다. 값이 true이면 프로퍼티의 값은 변경 가능하고, false이면 변경 불가능합니다.
    • [[Enumerable]]: 프로퍼티가 for...in 루프 등에서 나열 가능한지 여부를 나타내는 내부 슬롯입니다.
    • [[Configurable]]: 프로퍼티의 구성 가능성을 나타내는 내부 슬롯으로, delete 연산자를 통해 프로퍼티를 삭제하거나 프로퍼티 어트리뷰트를 변경할 수 있는지 여부를 제어합니다.
  • 프로퍼티 어트리 뷰트에 직접 접근할 수는 없지만 Object.getOwnPropertyDescriptor메서드를 사용하여 간접적으로 확인할 수는 있음

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

프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있음

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

데이터 프로퍼티

  • 데이터 프로퍼티는 다음과 같은 프로퍼티 어트리뷰트를 갖음
  • 프로퍼티 어트리뷰트는 자바스크립트 엔진이 프로퍼티를 생성할 떄 기본값으로 자동 정의됨
  • 프로퍼티가 생성될 때 [[value]]의 값은 프로퍼티 값으로 초기화 되며 나머지 3개의 값은 true로 초기화 됨
  • 이는 프로퍼티를 동적 추가해도 마찬가지임

접근자 프로퍼티

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

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

// 접근자 프로퍼티를 통한 프로퍼티 값의 저장
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
person.fullName = 'Habin Kim';
console.log(person); // {firstName: 'Habin', lastName: 'Kim'}

// 접근자 프로퍼티를 통한 프로퍼티 값의 참조
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다.
console.log(person.fullName); // Haeun Kim

프로퍼티 어트리뷰트는 언제 필요하고 언제 사용해?

프로퍼티 어트리뷰트는 JavaScript에서 객체의 프로퍼티에 대한 특성을 정의하는 데 사용됩니다. 이러한 어트리뷰트는 프로퍼티의 동작과 제약을 결정하며, 다양한 시나리오에서 사용될 수 있습니다. 여러 가지 상황에서 프로퍼티 어트리뷰트가 필요하고 사용됩니다.

  1. 값의 제어 및 보호: 프로퍼티 어트리뷰트를 사용하여 값의 변경 여부([[Writable]]), 읽기 전용 여부, 혹은 값의 변경에 제약을 둘 수 있습니다. 이를 통해 객체의 상태를 제어하고 보호할 수 있습니다.

  2. Getter 및 Setter 함수 지정: 프로퍼티 어트리뷰트를 사용하여 프로퍼티에 대한 커스텀 Getter 및 Setter 함수를 지정할 수 있습니다. 이를 통해 프로퍼티에 접근하거나 값을 변경할 때 특정 동작을 수행할 수 있습니다.

  3. 프로퍼티 나열 제어: [[Enumerable]] 내부 슬롯을 사용하여 for...in 루프 등에서 프로퍼티가 나열되는지 여부를 제어할 수 있습니다. 일부 프로퍼티는 나열되지 않도록 숨길 수 있습니다.

  4. 구성 가능성 제어: [[Configurable]] 내부 슬롯을 사용하여 프로퍼티의 구성 가능성을 제어할 수 있습니다. 이를 통해 프로퍼티를 삭제하거나 프로퍼티의 어트리뷰트를 변경할 수 있는지 여부를 결정할 수 있습니다.

프로퍼티 어트리뷰트는 객체 지향 프로그래밍에서 중요한 역할을 하며, 코드의 안전성, 유지 보수성, 그리고 프로퍼티의 동작을 정확히 제어하기 위해 사용됩니다. 객체의 프로퍼티에 대한 세부적인 제어를 필요로 하는 경우에 프로퍼티 어트리뷰트를 사용하게 됩니다.


Getter 및 Setter 함수는 왜 필요하고 어디에 사용해?

Getter 및 Setter 함수는 객체의 프로퍼티에 접근하거나 값을 변경할 때 특정 동작을 수행하기 위해 사용됩니다. 이러한 함수들은 프로퍼티에 접근하거나 값을 설정할 때 일종의 중간 단계로 동작하여, 개발자에게 추가적인 로직을 삽입할 수 있는 기회를 제공합니다. Getter는 프로퍼티 값을 읽을 때, Setter는 프로퍼티에 값을 할당할 때 호출됩니다.

Getter 함수의 활용:

  1. 가상 프로퍼티 생성: Getter를 사용하여 객체에 가상 프로퍼티를 동적으로 생성할 수 있습니다. 실제로 객체에 해당 프로퍼티가 존재하지 않더라도, Getter를 통해 필요한 값을 가상으로 생성하거나 계산할 수 있습니다.
const person = {
  firstName: "John",
  lastName: "Doe",
  get fullName() {
    return this.firstName + " " + this.lastName;
  }
};

console.log(person.fullName); // "John Doe"
  1. 프로퍼티 접근 제어: Getter를 사용하여 특정 조건에 따라 프로퍼티에 접근을 제어할 수 있습니다. 예를 들어, 특정 조건이 충족되지 않으면 값을 반환하지 않도록 구현할 수 있습니다.

Setter 함수의 활용:

  1. 값의 유효성 검사: Setter를 사용하여 프로퍼티에 값을 할당하기 전에 유효성을 검사하고 필요에 따라 수정할 수 있습니다.
const person = {
  _age: 0,
  set age(value) {
    if (value >= 0) {
      this._age = value;
    } else {
      console.error("Age cannot be negative");
    }
  },
  get age() {
    return this._age;
  }
};

person.age = 25; // 유효한 값
person.age = -5; // 유효하지 않은 값, 에러 발생
  1. 부수 효과 추가: Setter를 사용하여 값이 변경될 때 부수적인 효과를 추가할 수 있습니다. 예를 들어, 값이 변경될 때 로깅이나 이벤트 발생 등을 처리할 수 있습니다.
const obj = {
  _value: 0,
  set value(newValue) {
    console.log(`Setting value to ${newValue}`);
    this._value = newValue;
  },
  get value() {
    return this._value;
  }
};

obj.value = 42; // Setting value to 42

Getter 및 Setter 함수는 객체의 프로퍼티에 대한 접근 및 수정을 더 유연하게 제어하기 위해 사용됩니다. 이를 통해 코드의 가독성을 높이고 유지 보수성을 강화할 수 있습니다.


참고 자료

  • 이웅모,『모던 자바스크립트 Deep Dive』, 위키북스(2021), p219-233.
profile
아이디어와 구현을 좋아합니다!

0개의 댓글