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

标签 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.

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

最佳答案

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

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

您可以在 test 上使用 C 调用任何方法:

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 的一个实例,事后通过处理原型(prototype):

Object.setPrototypeOf(test, C);

setPrototypeOf会将 testB 的引用替换为对 C 的引用,并且 C.prototype 上的任何方法都将是可通过 test 访问,就像上面显式的 C.prototype 调用一样,但不需要指定 this 并使用 .call.

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

关于javascript - 我可以在 javascript 中将一个类的实例动态转换为另一个类的实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38206606/

相关文章:

javascript - 文字对象和 jquery 选择器 DRY

javascript - Ajax 请求链接/嵌套?

javascript - 流类型不适用于匿名函数内的外部作用域变量

javascript - 在 React 中将事件处理程序放置在匿名函数中如何解决绑定(bind)问题?

javascript - 使用 ES6 装饰器时出现意外标记 '@'

javascript - 比较对象内的键值是否重复更新

javascript - 使用 PostgreSQL 构建具有逻辑的 promise 链

javascript - HTML5 - 如何离线使用远程但缓存在 list 中的资源?

javascript - 错误。内容/形式不变

javascript - 将 JSON 数据数组分组到另一个数组