책정리/Deep Dive Javascript

객체 프로퍼티 접근, 변경 시 내부 동작 방식 (Javascript)

뽀글보리 2023. 11. 25. 08:24
반응형

들어가며

우리는 자바스크립트에서 코드를 작성할 때 많은 객체를 생성하고 접근하고 변경한다.

const person = {
  name: 'Lee'
}

person.name = 'Kim';
person.age = 20;

 

다음은 person이라는 객체를 만들고 name, age라는 프로퍼티를 정의하는 코드이다. 이 때, 자바스크립트는 const 객체를 선언하기 때문에 메모리 공간에 객체 참조 공간을 할당하고, 값을 저장할 것이다. (변수에 대해서 궁금하다면 클릭) 그렇다면 자바스크립트에서는 프로퍼티에 대한 정보를 어떻게 관리할까?

 

 

내부 슬롯과 내부 메서드

모든 객체는 내부 슬롯과 내부 메서드를 가진다. (관련 문서) 이는 자바스크립트 엔진의 내부 로직이다. 하나를 예로 들자면 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖고, 프로퍼티를 생성할 때 프로퍼티의 상태를 나타내는 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]와 같은 프로퍼티 어트리뷰트를 기본값으로 자동 정의한다. 이도 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯이다.

 

 

getOwnPropertyDescriptor 메서드

 

자바스크립트 엔진이 자동으로 생성하는 프로퍼티 어트리뷰트를 Object.getOwnPropertyDescriptor 메서드를 사용하여 확인해볼 수 있다.

const person = {
  name: 'Lee'
}

person.age = 20;


console.log(Object.getOwnPropertyDescriptor(person));

/*
{
  name: {value: "Lee", writable: true, enumerable: true, configurable: true},
  age: {value: 20, writable: true, enumerable: true, configurable: true}
}
*/

 

 

데이터 프로퍼티의 종류

참고

  • value
    • 프로퍼티 값
    • 값을 변경하면 value에 재할당한다.
  • writable
    • 프로퍼티 값의 변경 가능 여부
    • false일 경우 읽기 전용 프로퍼티
  • enumerable
    • 프로퍼티의 열거 가능 여부
    • false일 경우 for문이나 Object.keys 메서드 등으로 열거할 수 없다.
  • configurable
    • 프로퍼티의 재정의 가능 여부
    • false인 경우 프로퍼티 삭제와 프로퍼티 어트리뷰트 값의 변경이 금지된다. (writable=true일 경우 값 변경 가능)

 

접근자 프로퍼티의 종류

접근자 프로퍼티란 값을 갖지 않고 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수로 구성된 프로퍼티이다.

  • get
    • 접근자 프로퍼티를 통해서 값을 읽을 때 호출되는 접근자 함수
  • set
    • 접근자 프로퍼티를 사용해 값을 저장할 때 호출되는 접근자 함수
  • enumerable
  • configurable

ECMAScript에 따르면 enumerable, configurable은 데이터 프로퍼티와 접근자 프로퍼티에 중복 해당된다.

 

 

프로퍼티 참조

const person = {
  name: 'Lee'
}

console.log(person.name);

 

위 코드에서 person 객체의 name 프로퍼티를 참조할 때 자바스크립트 엔진 내부에서는 어떤 일이 일어날까?

 

 

  1. 프로퍼티 키 name이 유효한지 확인한다. 프로퍼티 키는 '문자열' 또는 '심벌'이어야 한다. 프로퍼티 키 "fullName"은 문자열이므로 유효한 프로퍼티 키다.
  2. 프로토타입 체인에서 프로퍼티를 검색한다. person 객체에 name 프로퍼티가 존재하는 지 확인한다.
  3. name 프로퍼티가 데이터 프로퍼티인지 접근자 프로퍼티인지 확인한다. name은 접근자 프로퍼티이다.
  4. 접근자 프로퍼티 name의 프로퍼티 어트리뷰트 get의 값, 즉 getter 함수를 호출하여 결과를 반환한다.

 

 

프로퍼티 정의

Object.definedProperty 메서드를 사용하여 프로퍼티 어트리뷰트를 정의할 수 있다.

 

var o = {}; // Creates a new object

// Example of an object property added with defineProperty with an accessor property descriptor
var bValue = 38;
Object.defineProperty(o, 'b', {
  get: function() { return bValue; },
  set: function(newValue) { bValue = newValue; },
  writable: true,
  enumerable: true,
  configurable: true
});
  • o라는 객체에 b라는 이름의 프로퍼티를 정의하는 메소드를 호출하였다.
  • o.b를 접근하면 getter 함수가 호출되어 38이 나온다.
  • writable = true이기 때문에 o.b = 10; 과 같이 값을 재할당할 수 있다.
  • configurable = true이 때문에 delete o.b와 같이 값을 삭제할 수 있다.
  • enumerable = true이기 때문에 for i in o.b와 같이 for 문을 사용할 수 있다.

 

 

참조

- 모던 자바스크립트 Deep Dive 16장

- https://262.ecma-international.org/6.0/#sec-object-internal-methods-and-internal-slots

반응형