프로퍼티 플래그


객체는 값(value) 외에도 플래그(flag)라는 특별상 속성이 있다. 플래그는 아래 3가지 종류가 있다. 일반적으로 객체를 선언하면(객체 리터럴 혹은 Object 생성자 함수 사용) 프로퍼티의 플래그는 true를 기본값으로 가진다.

프로퍼티 값 수정 프로퍼티 삭제 반복문 나열 플래그 수정
writable: false
enumerable: false
configurable: false
  1. writable (수정)
    1. true : 프로퍼티 값 수정 가능
    2. false : 프로퍼티 값 수정 불가(프로퍼티 삭제는 가능)
  2. enumerable (열거)
    1. true : 반복문으로 나열 가능
    2. false : 반복문으로 나열 불가
  3. configurable
    1. true : 프로퍼티 삭제 / 플래그 수정 가능
    2. false : 프로퍼티 삭제(프로퍼티 값 수정은 가능) / 플래그 수정 불가

프로퍼티 설명자 객체 — Object.getOwnPropertyDescriptor

프로퍼티에 대한 정보는 Object.getOwnPropertyDescriptor 메서드를 이용해 얻을 수 있다. 이 메서드를 호출하면 프로퍼티 설명자(descriptor)라는 객체가 반환된다. 이 설명자 객체에 플래그 정보가 담겨있다.

Object.getOwnPropertyDescriptor(obj, property)

const user = { name: 'john', age: 30 }
const descriptor = Object.getOwnPropertyDescriptor(user, 'name')

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

프로퍼티 / 플래그 정의 및 변경 — Object.defineProperty

<aside> 💡 객체 리터럴, 객체 복사(Object.assign, 전개연산자)등으로 만든 객체의 모든 플래그 기본값은 true. Object.defineProperty로 프로퍼티를 추가할 때 명시하지 않은 모든 플래그 기본값은 false

</aside>

Object.defineProperty 메서드를 사용하면 객체의 플래그를 변경할 수 있다. 인자로 넘겨받은 정보를 이용해 새로운 프로퍼티를 생성해준다. 이때 플래그 정보를 명시하지 않으면 플래그 값은 자동으로 false가 된다.

Object.defineProperty(obj, property, descriptors)

const user = {};
Object.defineProperty(user, 'name', {
  value: 'johan'
})

console.log(user) // {name: 'johan'}
console.log(Object.getOwnPropertyDescriptor(user, 'name'))
// {value: 'johan', writable: false, enumerable: false, configurable: false}

writable 플래그

writable 플래그를 이용해 객체의 특정 속성의 값을 쓰지 못하도록(non-writable) 할 수 있다. 에러는 엄격 모드("use strict")에서만 발생한다.

const user = { name: 'john' };

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

user.name = 'smith' // Error: Cannot assign to read only property 'name'
console.log(user) // {name: 'john'}