JavascriptのClassをShallow Copyする

TL;DR

ReactのuseStateObject.isを使用して処理の更新を検知している。

Arrayや単純なObjectを利用する場合はスプレッド構文などを利用することで更新することができる。 スプレッド構文はいわゆるShallow Copyを提供するわけだが、これをclassで利用したい。

classの場合

結論としては以下のようなメソッドで解決できる。

clone() {
    const clone = Object.assign({}, this);
    Object.setPrototypeOf(clone, Object.getPrototypeOf(this));
    return clone;
}

実際の例は以下

class Entity {
  constructor(a) {
    this.a = a;
  }

  getA() {
    return this.a;
  }

  clone() {
    const clone = Object.assign({}, this);
    Object.setPrototypeOf(clone, Object.getPrototypeOf(this));
    return clone;
  }
}

const entity = new Entity(1);

// spreadするとObject.isの結果はfalseになるが、メソッドが消える
// 単純にobjectになっているだけなのでそれはそう
const o = { ...entity };
Object.is(o, entity);
// false

o.getA();
// Uncaught TypeError: o.getA is not a function

// cloneを使うとメソッドも保存される
const entity_clone = entity.clone();

Object.is(entity_clone, entity);
// false

entity_clone.getA();
// 1

Reference

この記事に関するIssueをGithubで作成する

Read Next