Object.defineProperty()の使い方

Object.defineProperty()の使い方

TypeScriptでlocation.reloadをspyOnしようとして、できなかったので色々調べていたら、Object.defineProperty()、Object.getOwnPropertyDescriptor()というメソッドを発見しました。

以下を実行します。

console.log(Object.getOwnPropertyDescriptor(window.location,'reload'));

結果は以下のようになります。configurableもwritableもfalseなんです。

Object
  configurable:false
  enumerable:true
  value:ƒ reload()
  writable:false
  __proto__:Object

各プロパティの意味は以下の通りです。

項目 内容
writable 書き込み可否
enumerable 列挙可否
configurable 再定義可否

writable:falseの場合、代入することができません。

const obj = {};
Object.defineProperty(obj, 'x', {
  value : 1,
  writable : false,
  enumerable : true,
  configurable : true
});
console.log(obj.x); // ここでは1
obj.x = 2;
console.log(obj.x); // 書き込み不可なので、ここでも1

次にenumerable:falseのオブジェクトを作成してみます。列挙不可にするために、複数プロパティを定義します。その際は、Object.defineProperties()メソッドを使用します。

const obj = Object.defineProperties({}, {
  x : { value: 1, writable: true, enumerable: true, configurable: true },
  y : { value: 2, writable: true, enumerable: false, configurable: true }
});
// obj = {x:1,y:2};となる

プロパティのyはenumerable:falseなので、Object.keysなどで列挙されません。

const obj = Object.defineProperties({}, {
  x : { value: 1, writable: true, enumerable: true, configurable: true },
  y : { value: 2, writable: true, enumerable: false, configurable: true }
});
const keys = Object.keys(obj);
keys.forEach(i => {
  console.log(i);
})
// xだけ表示される
// keys.lengthは1

次にconfigurable:falseのオブジェクトを作成してみます。再定義が不可になります。

具体的には、書き込みは問題ありません。

const obj = Object.defineProperties({}, {
  x : { value: 1, writable: true, enumerable: true, configurable: true },
  y : { value: 2, writable: true, enumerable: true, configurable: false }
});
obj.y = 10;
console.log(obj.y); // 10と表示される

具体的に再定義が不可というのはどういうことかというと、どうもObject.defineProperty()などで再定義することが不可なようです。

const obj = Object.defineProperties({}, {
  x : { value: 1, writable: true, enumerable: true, configurable: true },
  y : { value: 2, writable: true, enumerable: true, configurable: false } // 再定義不可とする
});

Object.defineProperty(obj, 'x', {
  value: 1,
  writable: true,
  enumerable: true,
  configurable: true
}); // これはOK

Object.defineProperty(obj, 'y', {
  value: 1,
  writable: true,
  enumerable: true,
  configurable: true
}); // これはNG,再定義不可で定義しているため。

上記コードを実行すると

Uncaught TypeError: Cannot redefine property: y

というエラーが発生します。

Object.defineProperty()の使い方

コメント

株式会社CONFRAGE ITソリューション事業部をもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む

タイトルとURLをコピーしました