JavaScriptのECMAScript2017 仕様の新機能の1つは、getOwnPropertyDescriptorsメソッドです。 簡単に言うと、このメソッドは、ゲッターとセッターに関する情報を含む、指定されたオブジェクトのすべてのプロパティの情報を返します。 これにより、オブジェクトのコピーを作成し、ゲッターやセッターを含むすべてのプロパティをコピーしながらクローンを作成できます。

JavaScriptでは、オブジェクト内でメソッドとして動作し、オブジェクト外でプロパティとして動作する特別なプロパティを作成できます。 それらはgetおよびsetと呼ばれます。

// object with get and set properties

const gator = {
  name: 'Ben',
  type: 'reptilian',
  get fullName(){
    return `${this.name}${this.type}`;
  },
  set gatorName(name){
    this.name = name;
  }
};  

console.log(gator)を実行すると、名前とタイプのみが取得されます。 それでも、コンソールに表示されていないにもかかわらず、getterfullNameにアクセスできます。

console.log(gator)      // {name: 'Ben',  type: 'reptilian',}
console.log(gator.fullName) // 'Benreptilian'

メソッドではなく、通常のプロパティであるかのようにゲッターを呼び出すことに注意してください。

オブジェクトのクローン作成

Object.assign()を使用して、javaScriptでオブジェクトのクローンを作成します。 Object.assignメソッドに慣れていない場合は、JavaScriptでオブジェクトを管理する方法に関するの記事をお読みください。 このメソッドの主な問題は、オブジェクトのクローンを作成するときに、期待どおりの結果が得られないことです。 このメソッドは、ゲッターとセッターでは機能しません。

const cayman = {Object.assign({}, gator};
console.log(cayman)         // {name: 'Ben',  type: 'reptilian', fullName: Benreptilian, gatorName: undefined }

そのため、ゲッターとセッターは通常の値になりました。 また、ゲッターがカウンター値の場合、セッターは未定義になります。

代わりに、getOwnPropertyDescriptorsメソッドを使用してオブジェクトのクローンを作成しましょう。

const crocodilian = Object.defineProperties({}, Object.getOwnPropertyDescriptors(gator)));

次に、持っている各オブジェクトの記述子を比較してみましょう。

console.log(Object.getOwnPropertyDescriptors(gator));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        
*/

console.log(Object.getOwnPropertyDescriptors(cayman));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {value: 'Benreptilian', writable: true, enumerable: '', configurable: ''},
    gatorName: {value: undefined, writable: true, enumerable: '', configurable: ''},        
*/

console.log(Object.getOwnPropertyDescriptors(crocodilian));

/*  name: {value:'Ben', writable: true, enumerable: true, configurable: true},
    type: {value:'reptilian', writable: true, enumerable: true, configurable: true},
    fullName: {get: f, set: undefined, enumerable: '', configurable: ''},
    gatorName: {get: undefined, set: f, enumerable: '', configurable: ''},        

*/

gatorのオブジェクトプロパティnametypeは通常のプロパティとして定義されていますが、fullNameとgatorNameはgetterとsetterとして定義されています。 valueフィールドはありませんが、getおよびsetフィールドがあります。 caymanのオブジェクトゲッターとセッターは、通常の値として記述されています。 そして、crocodilianオブジェクトを使用すると、getOwnPropertyDescriptorsのおかげで、ゲッターとセッターを保存することができます。

getOwnPropertyDescriptorsメソッドは、データの損失を回避するのに役立ち、別のユーティリティ関数に依存することなく、オブジェクトのディープコピーを作成できます。