Javascript | 객체 flag과 defineProperty

이동욱·2024년 1월 12일
0

객체의 플래그?

일반적으로 객체를 생각하면 key-value형식의 프로퍼티를 생각한다.
여기서 좀 더 파고들면 value의 속성을 지정하는 flag들이 있다.

  • writable – 변경가능여부
  • enumerable – for...in , Object.keys()와 같은 메소드에서 호출 가능여부
  • configurable – 프로퍼티 삭제, flag 수정 가능여부

아래와 같이 일반적 선언으로 생성한 객체들은 이러한 flag값을 true 로 자동 설정한다.

const user = {
  name: "ddowoo",
};


플래그 다루기

getOwnPropertyDescriptor()

  • 객체 특정 프로퍼티의 플래그 값을 반환한다.
  • getOwnPropertyDescriptor(객체, key)
    • 객체 - 조회 대상 객체
    • key - 프로퍼티의 key값
const user = {
  name: "ddowoo",
};

console.log(Object.getOwnPropertyDescriptor(user, "name"));

// {
//   value: 'ddowoo',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }


플래그 설정, 수정

Object.defineProperty()

  • 객체 특정 프로퍼티의 값, 플래그, getter, setter를 설정할 수 있다.
  • getOwnPropertyDescriptor(객체, key, config)
    • 객체 - 수정 대상 객체
    • key - 대상 프로퍼티의 키값
    • config
      • writable - 수정 가능 여부
      • enumerable - for in, Obejct.keys에서 프로퍼티 추출 가능 여부
      • configurable - 프로퍼티 삭제, flag 변경 가능 여부

defineProperty를 이용해 프로퍼티를 설정하면 flag들의 기본값은 false로 설정된다

const user = {};

Object.defineProperty(user, "name", {
  value: "ddowoo",
});

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

1. writable

writable를 false로 셋팅하면 해당 프로퍼티 value값의 수정이 불가능하다.

const user = {};

Object.defineProperty(user, "name", {
  value: "ddowoo",
	writable:false,
  configurable: true, //writable flag를 다시 설정하기 위해 true값으로 셋팅
});
console.log(user.name); //ddowoo
user.name = "minSu";
console.log(user.name); //ddowoo (수정 안됨)

//-----------------------------

Object.defineProperty(user, "name", {
  value: "ddowoo",
  writable: true,
});

console.log(user.name); //ddowoo
user.name = "minSu";
console.log(user.name); //minSu
💡 `configurable`를 `false`값으로 하면 flag 변경이 불가능 하기 때문에 다시 defineProperty를 하면 TypeError가 발생한다!

2. enumerable

false로 셋팅하면 for in, Obejct.keys 와 같은 연산에서 프로퍼티 조회가 불가능하다.

또한 객체 전체를 조회했을 때도 걸러져 조회되지 않는다.

const user = {};

Object.defineProperty(user, "name", {
  value: "ddowoo",
  configurable: true,
  enumerable: false,
});

console.log(user.name) // ddowoo (조회 가능)
console.log(user)  // {} (조회 불가)
console.log(Object.keys(user)); // []  (조회 불가)

//--------------------------------

Object.defineProperty(user, "name", {
  value: "ddowoo",
  enumerable: true,
});

console.log(Object.keys(user)); // ['name']

3. configurable

false 로 설정시 프로퍼티 제거 및 flag설정 변경이 불가능하다.

const user = {};

Object.defineProperty(user, "name", {
  value: "ddowoo",
  configurable: false,
});

delete user.name; 
console.log(user.name); // ddowoo (제거 안됨)

4. get, set

get,set은 객체 프로퍼티에 조회, 값 설정 시 실행된다.
get, set은 value와 함께 쓰일수 없고 writable 역시 true값을 셋팅 할 수 없다.
만약 value와 writable를 함께 쓸경우 TypeError가 발생한다.

const user = {};
let _name = "";

Object.defineProperty(user, "name", {
  enumerable: true,
  configurable: true,
  set(value) {
    _name = value;
  },
  get() {
    return _name;
  },
});

console.log(user.name); // '' (빈배열)
user.name = "Minsu";
console.log(user.name); // Minsu

참조
Object.defineProperty에 대해서
Mdn Object.defineProperty()
Object.defineProperty 에 대하여 알아보기

profile
프론트엔드

0개의 댓글