Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ES6从现有实例实例化派生类_Javascript_Ecmascript 6 - Fatal编程技术网

Javascript ES6从现有实例实例化派生类

Javascript ES6从现有实例实例化派生类,javascript,ecmascript-6,Javascript,Ecmascript 6,考虑以下场景: class A { constructor() { this.A = 'A'; } createB() { //Create a B instance from this current instance } } class B extends A { constructor() { super(); this.B = 'B'; } } var base = new A(); var derived = new B()

考虑以下场景:

class A {
  constructor() {
    this.A = 'A';
  }

  createB() {
    //Create a B instance from this current instance
  }
}

class B extends A {
  constructor() {
    super();
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = base.createB();
我希望能够创建
B
的实例,而不必创建
a
的新实例,而是使用现有的
a
实例

我的目标是能够通过调用
a
中的函数生成
B
实例,但也允许直接创建
B
实例,并处理构造默认
a
的操作


B
扩展
A
并需要调用
super()
时,我如何实现这样的目标?

不确定这正是您想要的,但它适用于您的示例:

class A {
  constructor() {
    this.A = 'A';
  }
}

class B extends A {
  constructor() {
    super();
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = new B();
Object.assign(fromInstance, base);

console.log(fromInstance);
这里有另一个解决方案。这在C#和Java中非常常见,但由于JS没有方法重载,这有点麻烦,与上述解决方案相比也不太好:

class A {
  constructor(source) {
    if(source){
      //use properties/stuff from source
      this.A=source.A;
    }
    else{
      //only perform initialization if source is not provided
      this.A = 'A';
    }
  }
}

class B extends A {
  constructor(source) {
    super(source);
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = new B(base);

console.log(fromInstance);
基本上,构造函数有两个版本,一个创建全新对象,另一个复制旧对象


我认为这有点误解,不管你做什么,
B
的每一个实例都是定义为
a
。如果您希望调用
super
,那么您正在调用
A
的构造函数,从而“实例化”
A
如果我理解这个问题,您希望新实例的
A
属性反映创建它的实例的
A
属性,对吗?您可以在
createB
中设置它,因为它将在
A
实例上调用。这将允许
B
实例具有隐藏继承的
a

A类{
构造函数(){
this.A='A';
}
createB(){
设b=新b()
b、 A=此。A//设置为实例“A”
返回b
}
}
B类扩展了A类{
构造函数(){
超级();
this.B='B';
}
}
var base=newa();
var派生=新的B();
base.A='C';
//从a创建一个B实例,以便
//一个新的a没有被实例化,并且
//fromInstance.A==='C'
var fromInstance=base.createB();

log(fromInstance)
通用方法可以将所有A实例属性复制到新的B实例。一种更通用的方法是先将B对象的属性复制到临时存储中,然后再将它们写回,这样,如果A和B具有相同的属性名称,则B对象的属性将优先:

A类{
构造函数(){
this.A='A';
}
createB(){
设b=新b();
设temp={};
让我们跳一跳,跳一跳;
//保存b的自身属性
Object.keys(b.forEach(bProp=>(temp[bProp]=b[bProp]);
//安装实例自己的属性
Object.keys(this.forEach)(aProp=>(b[aProp]=this[aProp]);
//在实例属性上写回b属性
Object.keys(temp.forEach)(bProp=>(this[bProp]=temp[bProp]);
返回b;
}
}
B类扩展了A类{
构造函数(){
超级();
this.B='B';
}
}
var base=newa();
var派生=新的B();
base.A='C';
//从a创建一个B实例,以便
//一个新的a没有被实例化,并且
//fromInstance.A==='C'
var fromInstance=base.createB();
console.log(“派生的.A=%s”,派生的.A);

log(“fromInstance.A=%s”,fromInstance.A)
只需创建
B
的实例,使用
对象将
A
的当前实例的属性复制到它。分配
然后返回它:

createB() {
    var b = new B();
    Object.assign(b, this);
    return b;
}
示例:

A类{
构造函数(){
this.A='A';
}
createB(){
var b=新的b();
对象。分配(b,本);
返回b;
}
}
B类扩展了A类{
构造函数(){
超级();
this.B='B';
}
}
var base=newa();
var派生=新的B();
base.A='C';
var fromInstance=base.createB();
log(来自B的实例instanceof);

log(fromInstance.A)
您确定
base.A
属性存在吗?是的,我已经更正了示例中的输入错误
this.Name
应该是
this.A
我想知道你为什么要这么做,而我现在画的是空白。你想实例化一个没有。。。实例化一个类?您想做什么,您认为您需要代码注释中描述的内容?因为我很确定这不是您真正需要的。@Mike'Pomax'Kamermans我正在将它应用到为MongoDB的NodeJS驱动程序编写的适配器集合中。有一个处理基本操作的
DbClient
基类和一个派生的
DbCollection
类。理想情况下,我可以直接实例化一个
DbCollection类
,并让它自动创建一个
DbClient
对象作为基础,以及能够直接从
DbClient
实例内部实例化
DbCollection
并将其用作基础,而不必创建一个全新的实例,我仍然不明白,如果您有一个
类B扩展了a
,那么您可以在B的
构造函数中执行任何您喜欢的操作,包括在“成为A”的过程中调用任何可用的内容。即使扩展类隐藏了A的函数,也有
super
关键字。你能编辑你的问题,让它真正反映你在做什么,你需要它做什么,而不是使用与类名同名的变量的类吗?这确实解决了手头的主要问题,但是,最好不要为
B
的基础构建一个全新的
a
实例,因为它将立即被替换。@Haus不管解决方案如何,如果我没有误解的话,您将不得不创建1
a
实例和N
B
实例。我将编辑答案以包含替代解决方案。