【问题标题】:How to dynamically extend ES5 and ES6 classes如何动态扩展 ES5 和 ES6 类
【发布时间】:2017-07-14 15:48:41
【问题描述】:

我正在尝试构建一个可在每个环境中使用的工具库。我有一个转译器,所以我生成的代码是 ES5。

问题是我的工具挂钩类方法并将它们注入原型中:

klass.prototype = Object.create(
  Object.getPrototypeOf(klass.prototype),
  modifiedDescriptors
);

但是如果传递了一个 ES6 类,我们不能修改它的 prototype,因为它的描述符是 {configurable: false, writable: false}。所以我决定用 ES5 代码完全扩展这个类,而不是修改原来的原型:

function ProxyCtor() { return klass.apply(this, arguments) }
ProxyCtor.prototype = Object.create(klass.prototype, modifiedDescriptors);

这也是不可能的,因为没有new 就无法调用 ES6 类构造函数:Class constructor X cannot be invoked without 'new'

好的,没问题,我将放弃 ES5 支持,我的代码将使用 ES6 类扩展该类,然后我最终将能够挂钩方法:

class ProxyCtor extends klass {}

Object.defineProperty(ProxyCtor, 'prototype', Object.create(
  Object.getPrototypeOf(ProxyCtor.prototype),
  modifiedDescriptors
);

这又失败了,因为ProxyCtor.prototype 是只读的,就像klass.prototype 一样。

我可以为此使用Proxy,但要求是支持旧版浏览器,并且出于优化原因,我需要在脚本启动时而不是在调用方法时执行计算。

所以问题是......我如何扩展一个 ES6 类(意味着它应该具有相同的行为,new ProxyCtor() instanceof klass 应该是真的)但用函数包装它的方法?

【问题讨论】:

  • 你会想看看装饰器提案。
  • 这个想法是把它用作装饰器,但它应该可以在不转换的项目中使用。事实上,即使用作装饰器,这段代码也应该被执行。

标签: javascript ecmascript-6


【解决方案1】:

您使用Object.create 用新对象覆盖.prototype 很容易

Object.defineProperties(klass.prototype, modifiedDescriptors)

保持对象不变但改变其属性。

【讨论】:

  • 确实,我试图保持不变性,但我们已经在改变类所以......非常感谢你的回答@bergi
猜你喜欢
  • 2019-11-18
  • 2018-11-28
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 2019-09-16
  • 2016-08-20
  • 2019-09-21
  • 1970-01-01
相关资源
最近更新 更多