Javascript 如何将克隆的函数分配给此新实例
我有以下用ES6编写的代码,以及一些第3阶段建议:Javascript 如何将克隆的函数分配给此新实例,javascript,es6-class,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 exten
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));
现场演示:
其思想是在更新实例的某些属性时创建实例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功能(传播、功能道具)
尝试为此使用扩展属性时会出现一些问题,尤其是您最终会得到一个原型为
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);
}
}
或者,如果您愿意,只需在创建复制的位置执行即可:
const copy = Object.assign(new Child(c.x), c, {x: 10});
在这两种情况下,如果您选择继续使用字段而不是方法,则必须进行调整,否则您将同时复制squareX
和printX
使用方法和复制构造函数的实时示例:
constructor(x, ...more){
if (x instanceof Child) {
// The copy constructor branch
super(x.x);
Object.assign(this, x, ...more);
} else {
super(x);
}
}
类父类{
构造器(x){
这个.x=x;
this.otherProperty=“跨副本保留”;
}
printX(){
console.log(this.x);
}
平方(){
this.x=this.x*this.x;
}
}
类子级扩展父级{
构造函数(x,…更多){
if(子对象的x实例){
超级(x.x);
赋值(这个,x,…更多);
}否则{
超级(x);
}
}
}
常数c=新生儿(20);
const copy=新的子级(c,{x:10});
log(JSON.stringify(c));
c、 平方();
log(JSON.stringify(c));
log(JSON.stringify(copy));
copy.squareX();
log(JSON.stringify(copy))代码>注意:“ES6”(ES2015)没有排列属性。事实上,他们甚至不在ES2017。他们可能在ES2018;当前是。它是更新类的选项吗?我想到的是一个静态工厂函数,它作为参数接受一个类实例,读取所需的属性,生成一个新实例,更新这些属性,然后返回新实例。与通过object Literal克隆旧实例不同,您正在使用的也不在任何规范中,而且也处于第3阶段。@T.J.Crowder:我实际上在使用Babel。我更新了答案以反映这一事实。好吧-代码将完全与函数
表达式一起工作。