我可以在javascript中动态地将一个类的实例转换为另一个类的实例吗?

我可以在javascript中动态地将一个类的实例转换为另一个类的实例吗?,javascript,ecmascript-6,Javascript,Ecmascript 6,python已经回答了这个问题: 但我很好奇,这是否可以在带有ES6/ES2015的Javascript中实现 class A { ... } class B extends A { ... } class C extends A { ... } let test = new B(); // ... After a while I want to have an instance of C instead of B in test. 这可能吗?还是一个坏主意?您必须为此编写一个方法或替换原

python已经回答了这个问题:

但我很好奇,这是否可以在带有ES6/ES2015的Javascript中实现

class A { ... }
class B extends A { ... }
class C extends A { ... }

let test = new B();

// ... After a while I want to have an instance of C instead of B in test.

这可能吗?还是一个坏主意?

您必须为此编写一个方法或替换原型(这可能被认为是一个非常坏的主意)。但是,通过控制
this
并直接调用方法,您可以将
B
的实例视为
C

由于JavaScript是duck类型的,并且没有强类型,因此传统的转换(通常是类型转换)几乎没有意义。所有状态和行为都附加到实例及其原型(甚至在运行时),而不是编译器对类型的理解

您可以使用以下方法从
test
上的
C
调用任何方法:

C.prototype.methodName.call(test, arg1, arg2);
使用指定的
this
调用函数,因此您可以对完全不相关的对象调用方法(只要它们共享一个契约,它就可以工作)

您始终可以声明一个副本构造函数,以将
B
转换为
C
,使用:

class C extends A {
  static fromB(other: B): C {
    return new C(B.foo, B.bar);
  }
}
(为了清晰起见,使用Flow/Typescript类型注释)

最后,也是我最不喜欢的,就是声称
test
实际上是
C
的一个实例,通过破坏原型:

Object.setPrototypeOf(test, C);
test
B
的引用替换为
C
的引用,并且
C.prototype
上的任何方法都可以通过
test
访问,就像上面显式的
C.prototype
调用一样,但无需指定
并使用
调用


您也可以选择将任何共享方法移动到
A
中的简单选项,并可能完全避免这个问题,但这些是与cast的JS等价物。

您能展示一个用例吗?JavaScript没有实际的类,它们只是语法糖,允许更简单的原型继承。您必须说明“转换”到另一个实例的含义。