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

时间:2016-07-05 14:54:10

标签: javascript ecmascript-6

python:Can I dynamically convert an instance of one class to another?

已经回答了这个问题

但我很好奇是否可以在带有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.

这可能吗?或者这是一个坏主意?

1 个答案:

答案 0 :(得分:3)

您必须为此编写一个方法或替换原型(这可能被认为是一个非常糟糕的想法)。但是,通过控制B并直接调用方法,您可以在很大程度上将C的实例视为this

由于JavaScript是鸭子类型且没有强类型,传统的转换(通常是类型转换)大多没有意义。所有状态和行为都附加到实例及其原型(即使在运行时),而不是编译器对类型的理解。

您可以使用以下网址C test拨打任何方法

C.prototype.methodName.call(test, arg1, arg2);

call method on a function使用指定的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);

setPrototypeOf会将test的引用替换为B并引用CC.prototype上的所有方法都可以通过{test访问{1}},与上面的明确C.prototype调用类似,但无需指定this并使用.call

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