상세 컨텐츠

본문 제목

javascript.info - 객체 프로퍼티 설정

개발공부/개발공부

by Dal_pang 2022. 12. 30. 11:00

본문

프로퍼티 플래그와 설명자.

객체에 설정할 수 있는 프로퍼티.

객체 프로퍼티는 플래그라는 특별한 속성 세 가지를 갖는다.

 

1) writable - true이면 값 수정 가능.

2) enumerable -true면 반복문 사용해 나열 가능. 

3) configurable - true이면 프로퍼티 삭제나 플래그 수정 가능.

 

 Object.getOwnPropertyDescriptor 메서드를 사용해 특정 프로퍼티에 대한 정보를 모두 얻기 가능.

let user = {
  name: "John"
};

let descriptor = Object.getOwnPropertyDescriptor(user, 'name');

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

플래그 변경 => Object.defineProperty

Object.defineProperty(obj, propertyName, descriptor)

 

 

Writable플래그, 값 쓰지 못하게 변경하기

let user = {
  name: "John"
};

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

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

 

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

enumerable : false인 프로퍼티는 열거되지 않음. Object.keys에도 배제된다.

 

 

Configurable 플래그

false인 경우 프로퍼티 쓰기, 열거, 구성 불가. 주요 예) Math의 PI프로퍼티.

 

 

 

Object.defineProperties

프로퍼티 여러 개를 한 번에 정의 가능.

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

 

 

Object.getOwnPropertyDescriptors

 

프로퍼티 설명자를 전부 한꺼번에 가져올 수 있다.

특히, Object.defineProperties와 함께 사용하면 객체 복사 시 플래그도 함께 복사 가능.

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

// 위 방법은 플래그 정보도 복사하기 위해서 사용하는 방법.

기존의 프로퍼티 복사 방법을 통한 객체 복사방법은 플래그 정보 복사가 안됬음

기존 방식)

for (let key in user) {
  clone[key] = user[key]
}

 


프로퍼티 getter와 setter

접근자 프로퍼티 : getter , setter

let obj = {
  get propName() {
    // getter, obj.propName을 실행할 때 실행되는 코드
  },

  set propName(value) {
    // setter, obj.propName = value를 실행할 때 실행되는 코드
  }
};

실제 사용 예)

실제 값은 _name 프로퍼티에 저장되고, 값을 읽어올 때는 user.name(getter사용)으로 읽어옴.

let user = {
  get name() {
    return this._name;
  },

  set name(value) {
    if (value.length < 4) {
      alert("입력하신 값이 너무 짧습니다. 네 글자 이상으로 구성된 이름을 입력하세요.");
      return;
    }
    this._name = value;
  }
};

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

user.name = ""; // 너무 짧은 이름을 할당하려 함

호환성을 위해 접근자 프로퍼티 사용.

example) age값을 입력 받는 대신, Birthday를 입력받기로 수정한 경우 다음과 같이 코드 수정 가능.

function User(name, birthday) {
  this.name = name;
  this.birthday = birthday;

  // age는 현재 날짜와 생일을 기준으로 계산됩니다.
  Object.defineProperty(this, "age", {
    get() {
      let todayYear = new Date().getFullYear();
      return todayYear - this.birthday.getFullYear();
    }
  });
}

let john = new User("John", new Date(1992, 6, 1));

alert( john.birthday ); // birthday를 사용할 수 있습니다.
alert( john.age );      // age 역시 사용할 수 있습니다.
728x90

관련글 더보기