Property flags and descriptors


相手は普段見えないシルエットwritableenumerableconfiguablegettersetterです.

1. property flags


1-1. writable

writableおよびtrueは、値を変更することができる
let user = {
  name: "John"
};

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

user.name = "Pete"; // Error: Cannot assign to read only property 'name'
したがって、上記のようにfalseに設定するとエラーが発生する
📌 エラーはstrict modeでのみ発生します

1-2. enumerable

enumerableおよびtrueは、繰り返し文を使用してリストできます.
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
toStringメソッドは、繰り返し文でリストできません.

1-3. configurable

configurableおよびtrueは、番組フラグを削除または変更することができる
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
// 수정도 불가능하지만 지우는 것 역시 불가능합니다.
つまり、変更できないオブジェクトを作成することができます.

2. getter, setter


オブジェクトのプロパティは2つに分類されます

  • データ属性(dataproperty)

  • アクセス者プロパティ(accessor property)としてget、setの役割を担当する
  • let obj = {
      get propName() {
        // getter, obj.propName을 실행할 때 실행되는 코드
      },
    
      set propName(value) {
        // setter, obj.propName = value를 실행할 때 실행되는 코드
      }
    };
    getterメソッドは、obj.propNameを使用してプロパティの読み取りを試みたときに実行される.setterメソッドはobj.propName = valueであり、propertyに値を付与しようとすると実行される
    let user = {
      name: "John",
      surname: "Smith",
    
      get fullName() {
        return `${this.name} ${this.surname}`;
      },
    
      set fullName(value) {
        [this.name, this.surname] = value.split(" ");
      }
    };
    
    alert(user.fullName); // John Smith
    
    // 주어진 값을 사용해 set fullName이 실행됩니다.
    user.fullName = "Alice Cooper";
    
    alert(user.name); // Alice
    alert(user.surname); // Cooper
    このようにgetter,setterメソッドを実現すると,オブジェクトはfullNameという仮想的なpropertyを生み出す.
    「仮象」の番組なので読み書きは可能ですが、実際には存在しません.
    これらのgettersetter関数は、変更不可能なpropertyを作成するのに適しています.
    たとえば、生年月日を入力すると、自動的に年齢パーセントを取得したいが、勝手に年齢を変更することはできない.
    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 역시 사용할 수 있습니다.
    ここには他のsetter関数はありません.ageは読み込めません.変更できません.
    📌 アクセス者propertyは、データpropertyとは異なり、valuewritableではなく、getsetという関数があります.

    *References

  • Propertyフラグと記述子
  • プロパティgetterとsetter