320x100
320x100

프로퍼티 플래그와 설명자

: 객체에는 프로퍼티가 저장 됨

: 프로퍼티는 키-값 쌍의 구조의 단순한 자료구조가 아닌 유연하고 강력한 자료구조 임

 

 

 

프로퍼티 플래그

: 객체 프로퍼티는 값과 플래그라는 특별한 속성 3가지를 가짐

 

- writable

: 값을 수정할 수 있는 여부

 

- enumerable

: 반복문을 사용해 나열 할수 있는 여부

 

- configurable

: 프로퍼티 삭제나 플래그 수정 가능 여부

 

=> 일반적인 방식으로 프로퍼티를 생성하면 해당 프로퍼티의 플래그는 모두 true가 되며 언제든지 수정 가능

 

 

 

 

 

Object.getOwnPropertyDescriptor

: 특정 프로퍼티에 대한 모든 정보를 얻을 수 있음

let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);

- obj 

: 정보를 얻고자 하는 객체

 

- propertyName

: 정보를 얻고자 하는 객체 내 프로퍼티

 

 

 

 

Object.defineProperty

: 객체와 프로퍼티의 플래그를 변경

Object.defineProperty(obj, propertyName, descriptor)

- obj

: 설명자를 적용하고 싶은 객체

 

- propertyName

: 설명자를 적용하고 싶은 객체와 객체 프로퍼티

 

- descriptor

: 적용하고자 하는 프로퍼티 설명자

 

=> 해당 객체의 프로퍼티가 없는 경우 새로운 프로퍼티를 만듬

=> 이때 플래그 값은 false

=> descriptor에 true를 명시해야함

 

 

 

 

Writable 플래그

let user = {
  name: "John"
};

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

user.name = "Pete"; // Error: Cannot assign to read only property 'name'

 

※ defineProperty를 이용하여 밑바닥 부터 만들기

let user = { };

Object.defineProperty(user, "name", {
  value: "John",
  // defineProperty를 사용해 새로운 프로퍼티를 만들 땐, 어떤 플래그를 true로 할지 명시해주어야 합니다.
  enumerable: true,
  configurable: true
});

alert(user.name); // John
user.name = "Pete"; // Error

 

 

 

 

 

enumerable 플래그

let user = {
  name: "John",
  toString() {
    return this.name;
  }
};

Object.defineProperty(user, "toString", {
  enumerable: false
});

// 이제 for...in을 사용해 toString을 열거할 수 없게 되었습니다.
for (let key in user) alert(key); // name

 

 

 

 

 

configurable 플래그

let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI');

alert( JSON.stringify(descriptor, null, 2 ) );
/*
{
  "value": 3.141592653589793,
  "writable": false,
  "enumerable": false,
  "configurable": false
}
*/


Math.PI = 3; // Error

// 수정도 불가능하지만 지우는 것 역시 불가능합니다.

 

 

 

 

영원히 변경할 수 없는 프로퍼티 만들기

let user = { };

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

// user.name 프로퍼티의 값이나 플래그를 변경할 수 없습니다.
// 아래와 같이 변경하려고 하면 에러가 발생합니다.
//   user.name = "Pete"
//   delete user.name
//   Object.defineProperty(user, "name", { value: "Pete" })
Object.defineProperty(user, "name", {writable: true}); // Error

 

 

 

 

 

Object.defineProperties

: 프로퍼티 여러 개를 한 번에 정의

Object.defineProperties(obj, {
  prop1: descriptor1,
  prop2: descriptor2
  // ...
});
Object.defineProperties(user, {
  name: { value: "John", writable: false },
  surname: { value: "Smith", writable: false },
  // ...
});

 

 

 

 

 

Object.getOwnPropertyDescriptors

: 프로퍼티 설명자를 한꺼번에 가져옴

: 이를 이용하여 객체 복사 시 플래그도 같이 가져올 수 있음

let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

 

 

 

 

객체 수정을 막아주는 다양한 메서드

- Object.preventExtensions(obj)
: 객체에 새로운 프로퍼티를 추가할 수 없게 함

 

- Object.seal(obj)
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제를 막아줌

: 프로퍼티 전체에 configurable: false를 설정하는 것과 동일한 효과

 

- Object.freeze(obj)
: 새로운 프로퍼티 추가나 기존 프로퍼티 삭제, 수정을 막아줌

: 프로퍼티 전체에 configurable: false, writable: false를 설정하는 것과 동일한 효과

 

 

※ 위 세 가지 메서드를 사용해서 설정한 제약사항을 확인할 때 사용할 수 있는 메서드
- Object.isExtensible(obj)
: 새로운 프로퍼티를 추가하는 게 불가능한 경우 false를, 그렇지 않은 경우 true를 반환

 

- Object.isSealed(obj)
: 프로퍼티 추가, 삭제가 불가능하고 모든 프로퍼티가 configurable: false이면 true를 반환

 

- Object.isFrozen(obj)
: 프로퍼티 추가, 삭제, 변경이 불가능하고 모든 프로퍼티가 configurable: false, writable: false이면 true를 반환

 

 

 

 

Refference

 

프로퍼티 플래그와 설명자

 

ko.javascript.info

 

300x250
728x90