햄스터 갬성 블로그

[FE 면접] 자바스크립트에서 어떻게 객체의 속성 변경을 막을 수 있을까?

면접 질문 #

객체(object)의 속성(property)의 변경을 막는 방법을 설명하라. 즉, 다음과 같이 이미 선언된 객체의 name 속성 변경을 막는 코드를 작성하라.

const guest = {
name: 'John',
age: 25
}

guest.name = 'Peter' // ?

나만의 대답 #

설명자(Descriptor)를 활용하여 객체의 속성값 변경을 막을 수 있다. 설명자는 말 그대로 객체의 한 속성에 대한 정보를 설명하는 값으로 다음과 같은 몇 가지 정보를 내포한다.

  1. value: 해당 속성의 값(위 코드에서 'John')
  2. writable: 해당 속성의 변경 가능 여부
  3. configurable: 해당 속성의 Object.defineProperty()를 통한 설정 가능 여부
  4. enumerable: 해당 속성이 열거 중에 나타나는 여부 (예를 들어, false로 설정하면 Object.values() 실행 중에 해당 속상이 나타나지 않는다)

설명자는 Object.getOwnPropertyDescriptor(object, property)를 통해 찾을 수 있다.

Object.getOwnPropertyDescriptor(guest, 'name')
// {value: 'John', writable: true, enumerable: true, configurable: true}

이 중에서 writable이 객체의 속성 변경과 관련되어 있다. 값을 false로 설정하면 해당 객체의 속성 변경을 막을 수 있다.

Object.defineProperty(object, property, descriptor)를 통해 설명자를 변경할 수 있다. 참고로 configurable이 false로 설정되어 있으면 위 함수를 통해 설정자 변경이 불가능하다. 다음과 같이 name 속성의 변경을 막을 수 있다.

Object.defineProperty(guest, 'name', { writable: false })

guest.name = 'Peter'
guest.name // 'John'

위에서 보듯이 name 속성 변경 시도에 에러가 발생하진 않지만 실제 값에 변경은 일어나지 않았다.

+알파 #

설명자를 통해 속성의 열거를 막을 수도 있다. enumerable을 false로 설정하면 된다.
만약 객체에 속한 모든 속성의 변경을 막고 싶으면 Object.freeze(object)를 사용하면 된다. 위 함수는 모든 속성의 writableconfigurable를 flase로 설정한다.

Object.freeze(guest)

Object.getOwnPropertyDescriptor(guest, 'name')
// {value: 'John', writable: false, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(guest, 'age')
// {value: 25, writable: false, enumerable: true, configurable: false}

Reference
Object.getOwnPropertyDescriptor() - JavaScript | MDN
Object.freeze() - JavaScript - MDN Web Docs