この解答例はChatGPTによって生成されています,正しいかは自己判断で。 皆の投稿からも解答例が見つかるかもしれませんよ。

BFE.devでのAI解答例 - JavaScript コーディング問題
27. completeAssign() を実装する

解法:

completeAssign()の実装には、Object.getOwnPropertyDescriptor()Object.defineProperty()を使う必要があります。Object.getOwnPropertyDescriptor()は、オブジェクトのプロパティのdescriptorを返します。Object.defineProperty()は、オブジェクトに新しいプロパティを追加または既存のプロパティを変更するために使用されます。

以下は、completeAssign()の実装です。

function completeAssign(target, ...sources) {  sources.forEach(source => {    Object.getOwnPropertyNames(source).forEach(propName => {      Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));    });    Object.getOwnPropertySymbols(source).forEach(propSymbol => {      Object.defineProperty(target, propSymbol, Object.getOwnPropertyDescriptor(source, propSymbol));    });  });  return target;}

この実装では、まずsourcesから1つずつオブジェクトを取り出し、Object.getOwnPropertyNames()Object.getOwnPropertySymbols()を使って、オブジェクトのすべてのプロパティの名前とSymbolを取得します。次に、各プロパティのdescriptorをObject.getOwnPropertyDescriptor()を使って取得し、Object.defineProperty()を使って、targetオブジェクトに追加または変更します。

以下は、これを実際に使った例です。

const source = Object.create(  {    a: 3 // prototype  },  {    b: {      value: 4,      enumerable: true // 列挙可能なdata descriptor    },    c: {      value: 5, // 枚举不可なdata descriptor    },    d: { // 枚举不可なaccessor descriptor       get: function() {        return this._d;      },      set: function(value) {        this._d = value      }    },    e: { // 列挙可能な accessor descriptor       get: function() {        return this._e;      },      set: function(value) {        this._e = value      },      enumerable: true    }  });const result = completeAssign({}, source);console.log(result); // { b: 4, c: 5, d: undefined, e: undefined }

この例では、sourceオブジェクトからtargetオブジェクトにプロパティがコピーされ、bcdeがtargetオブジェクトに保存されます。deは、Object.getOwnPropertyDescriptor()を使用して、getterおよびsetterを保持しているため、間違った値を保持することはありません。