我有以下代码,用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"
]
}
答案 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});
在任何一种情况下,如果您选择继续使用字段而不是方法,则必须进行调整,否则您也会复制squareX
和printX
。
使用方法和复制构造函数的实例:
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));