Object.assign ではプロトタイプまではコピーしてくれない

  • 2
    Like
  • 1
    Comment
More than 1 year has passed since last update.

JavaScript でオブジェクトをシャローコピーしようとしたときに Object.assign({}, obj) をよく使うのだが、オブジェクトのプロトタイプがコピーされていなくてハマったのでメモ。

class Foo {
  say() {
    console.log('foo');
  }
}

var foo = new Foo();
foo.say(); // foo

var copy_foo = Object.assign({}, foo);
copy_foo.say(); // TypeError: copy_foo.say is not a function

Object.assign は列挙可能なプロパティを assign してくるが、 __proto__ は列挙可能なプロパティではないので assign してくれない。

var copy_foo = Object.assign({ __proto__: foo.__proto__ }, foo);
copy_foo.say(); // foo

このように __proto__ を無理矢理 assign すれば動くっちゃ動くが、そもそも __proto__ を直接扱うのは非推奨 なので、もはや clone などのモジュールを使ったほうがいいと思われる。clone 使うとシャローコピーじゃなくてディープコピーになるけど。

var clone = require('clone');

var foo = clone(foo);
foo.say(); // foo