모던 자바스크립트 딥다이브, 면접과 함께 공부하기 - 16장 프로퍼티 어트리뷰트

지인·2023년 7월 24일
0

DeepDive

목록 보기
13/17
post-thumbnail

💡 아래 내용은 모던 자바스크립트 딥다이브를 공부하며 이해했던 내용을 다루고 있습니다. 혹시 틀렸거나 잘못된 정보가 있다면 알려주세요!

📌 16장 프로퍼티 어트리뷰트

JS에서 객체의 프로퍼티는 단순히 이름과 값이 연결된 것이 아니라, 그 이상의 정보들을 가지고 있습니다. "그 이상의 정보들"을 우리는 프로퍼티 어트리뷰트라고 부릅니다.

let obj = { name: 'John' };
let descriptor = Object.getOwnPropertyDescriptor(obj, 'name');

console.log(descriptor);
// {value: "John", writable: true, enumerable: true, configurable: true}

Object.defineProperty(obj, 'name', { writable: false });
console.log(descriptor);
// {value: "John", writable: false, enumerable: true, configurable: true}

16.1 내부 슬롯과 내부 메서드

내부 슬롯과 내부 메서드는 객체의 '뒷단'에서 일어나는 작업들을 말합니다. 이 둘은 객체가 어떻게 동작하는지, 데이터는 어떻게 저장되고 접근되는지에 대한 규칙을 정의하는 것들입니다.

내부 슬롯: 이것은 객체의 '데이터 저장소'라고 생각할 수 있습니다. 예를 들어, 만약 객체가 숫자를 저장하고 있다면, 그 숫자는 [[Value]]라는 내부 슬롯에 저장될 것입니다. 이런 내부 슬롯들은 코드에서 직접적으로 접근하거나 바꿀 수는 없습니다.

내부 메서드: 이것은 객체가 어떻게 동작해야 하는지를 정의하는 '규칙'입니다. 예를 들어, 객체의 특정 속성에 접근하려고 할 때, 자바스크립트는 [[Get]] 이라는 내부 메서드를 사용해서 그 속성 값을 찾아냅니다. 이런 내부 메서드들도 코드에서 직접적으로 호출할 수는 없습니다.

내부 슬롯은 접근이 불가능한 것이 원칙이지만, [[Prototype]] 내부 슬롯은 __proto__를 통해 간접적으로 접근할 수 있따.

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

프로퍼티 어트리뷰트에 직접 접근할 수 없기 때문에, 접근하기 위해 Object.getOwnPropertyDescriptor 메소드를 사용하여 사용되는 객체를 프로퍼티 스크립터 객체라고 합니다.

let obj = { a: 1 };
let descriptor = Object.getOwnPropertyDescriptor(obj, 'a');

console.log(descriptor);
// {value: 1, writable: true, enumerable: true, configurable: true}

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

자바스크립트 객체의 프로퍼티는 크게 데이터 프로퍼티와 접근자 프로퍼티 두 가지 유형이 있습니다.

16.3.1 데이터 프로퍼티

가장 일반적인 타입의 프로퍼티로, 단순한 값을 저장하는 용도로 사용됩니다. 데이터 프로퍼티는 value와 writable 두 가지 어트리뷰트를 가집니다. 아래 예제에서 a는 데이터 프로퍼티로, 값을 저장하는 역할을 합니다.

let obj = { a: 1 };
  1. [[Value]]: 프로퍼티가 가지고 있는 실제 값을 의미합니다. 예를 들어 let cat = { name: 'Nabi' };라고 선언했다면, 'name'이라는 프로퍼티의 [[Value]]는 'Nabi'가 됩니다.

  2. [[Writable]]: 프로퍼티의 값 변경 가능 여부. true면 변경 가능, false면 읽기 전용.

  3. [[Enumerable]]: 프로퍼티의 열거 가능 여부. true면 열거 가능, false면 열거 불가능.

  4. [[Configurable]]: 프로퍼티의 삭제 가능 여부, 프로퍼티 어트리뷰트의 변경 가능 여부. true면 가능, false면 불가능.

16.3.2 접근자 프로퍼티

값을 저장하기보다는, get과 set 메소드를 사용하여 특정 행동을 정의하는 용도로 사용됩니다. 접근자 프로퍼티는 get과 set 두 가지 어트리뷰트를 가집니다.

let person = {
  firstName: 'James',
  lastName: 'Bond',

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },

  set fullName(name) {
    let parts = name.split(' ');
    this.firstName = parts[0];
    this.lastName = parts[1];
  }
};

// fullName을 읽을 때 get 함수가 호출됩니다.
console.log(person.fullName); // 출력: "James Bond"

// fullName에 값을 할당할 때 set 함수가 호출됩니다.
person.fullName = 'John Doe';

16.4 프로퍼티 정의

새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것을 말합니다. 그 중에서 Object.defineProperty, Object.defineProperties 메서드를 이용하는 것이 가장 직접적인 방법입니다.

const person = {};

Object.defineProperty(person, 'firstName', {
  value: 'ABC'
});

16.5 객체 변경 방지

객체의 변경을 방지하기 위한 메서드들이 존재합니다.

16.5.1 객체 확장 금지

Object.preventExtensions(obj)로 새로운 프로퍼티 추가를 금지시킬 수 있으며, Object.isExtensible 메서드로 확장이 가능한 객체인지 여부를 확인할 수 있습니다.

16.5.2 객체 밀봉

Object.seal로 객체가 읽기와 쓰기만 가능한 상태로 변경할 수 있으며,
Object.isSealed 메서드로 밀봉된 객체인지 확인할 수 있습니다.

16.5.3 객체 동결

Object.freeze로 읽기만 가능한 상태로 변경할 수 있으며,
Object.isFrozen 메서드로 동결된 객체인지 확인할 수 있습니다.

16.5.4 불변 객체

객체 자체를 변경할 수 없도록 만드는 것을 말합니다. 이는 위의 세 가지 메서드와는 별개로, 프로그래머가 직접 코드를 작성할 때 불변성을 유지하도록 코드를 작성하는 것입니다.

profile
안녕하세요

0개의 댓글