如何将克隆函数分配给新的此实例

时间:2017-09-11 08:33:23

标签: javascript es6-class

我有以下代码,用ES6编写,加上一些第3阶段提案:

class Parent {
  constructor(x){
    this.x = x;
    this.otherProperty = "preserve across copy";
  }

  printX=()=>{
    console.log(this.x);
  }

  squareX=()=>{
    this.x = this.x *this.x; 
  }
}

class Child extends Parent {
  constructor(x){
    super(x);
  }  
}

const c = new Child(20);
const copy = {...c, x: 10};

console.log(JSON.stringify(c));
c.squareX();
console.log(JSON.stringify(c));

console.log(JSON.stringify(copy));
copy.squareX();
console.log(JSON.stringify(copy));

现场演示:https://jsbin.com/wuqenabaya/1/edit?js,console

我们的想法是创建实例c的副本,同时更新其中的一些属性。此代码的输出是:

{x:  20, otherProperty: "preserve across copy"}
{x: 400, otherProperty: "preserve across copy"}
{x:  10, otherProperty: "preserve across copy"}
{x:  10, otherProperty: "preserve across copy"}

因为您可以看到copy.squareX()未更新实例copy。问题是函数squareX()仍绑定到旧实例c

我想要的是最后一次调用squareX()来更新实例copy。如何实现这一目标?

编辑:我使用Babel和以下插件,以允许使用新的JS功能(传播,功能道具)。

{
  "presets": [
    ["es2015", { "modules": false }],
    "stage-0",
    "react"
  ],
  "plugins": [
    "react-hot-loader/babel",
    "transform-object-rest-spread",
    "transform-class-properties",
    "transform-flow-strip-types"
  ]
}

1 个答案:

答案 0 :(得分:2)

尝试为此使用spread属性存在一些问题,尤其是最终会得到一个原型为Object.prototype而非Child.prototype的对象。

你也在使用方法的字段语法,这使得那些字段拥有对象的属性,而不是原型属性,在这种情况下似乎没有任何理由;只需使用方法语法。

要进行复制,请在构造函数中给自己一个“复制构造函数”分支:

constructor(x, ...more){
  if (x instanceof Child) {
    // The copy constructor branch
    super(x.x);
    Object.assign(this, x, ...more);
  } else {
    super(x);
  }
}  

或者如果您愿意,只需在创建copy

的地方执行此操作
const copy = Object.assign(new Child(c.x), c, {x: 10});

在任何一种情况下,如果您选择继续使用字段而不是方法,则必须进行调整,否则您也会复制squareXprintX

使用方法和复制构造函数的实例:

class Parent {
  constructor(x){
    this.x = x;
    this.otherProperty = "preserve across copy";
  }

  printX() {
    console.log(this.x);
  }

  squareX() {
    this.x = this.x *this.x; 
  }
}

class Child extends Parent {
  constructor(x, ...more){
    if (x instanceof Child) {
      super(x.x);
      Object.assign(this, x, ...more);
    } else {
      super(x);
    }
  }  
}

const c = new Child(20);
const copy = new Child(c, {x: 10});

console.log(JSON.stringify(c));
c.squareX();
console.log(JSON.stringify(c));

console.log(JSON.stringify(copy));
copy.squareX();
console.log(JSON.stringify(copy));