javascript - 如何在 ES5 中实现“类扩展”功能(例如装饰器功能),该功能也适用于 ES2015 类
问题描述
我昨天问了一个类似的问题,它被标记为
ES6 的重复:调用类构造函数没有 new 关键字
由于上面链接的文档没有给出完整的答案,我现在问了同样的问题,今天有点不同......并在下面提供了一个可能的解决方案:
我如何必须在以下演示中实现 ES5 函数“扩展”(它应该只是扩展一个类)才能使用 ES2015 类而不会出现“类构造函数 baseClass 不能在没有'new'的情况下被调用”错误?
[编辑:“扩展”函数将成为(转译)ES5 库的一部分。这个库本身以后可能会被使用 ES5 或 >= ES2015 的其他人使用——这两种情况都应该有效]
// ES5 function (similar to: constr => class extends constr {})
function extend(constr) {
var ret = function () {
constr.apply(null, arguments)
}
ret.prototype = Object.create(constr.prototype)
return ret
}
// ES2015 code
const
baseClass = class {},
extendedClass = extend(baseClass)
new extendedClass() // <- Error: Class constructor baseClass cannot be invoked without 'new'
见: https ://jsfiddle.net/kjf7cheo/
一种解决方案可能如下所示(=> 使用“new Function(...)”)。这个解决方案有什么错误/不安全/需要考虑的吗?
var extend = null
if (typeof Proxy === 'function') { // check for ECMAScript version >= 2015
try {
extend =
new Function('baseClass', 'return class extends baseClass {}')
} catch (e) {
// ignore
}
}
if (!extend) {
extend = function (baseClass) {
var ret = function () {
baseClass.apply(this, arguments)
}
ret.prototype = Object.create(baseClass.prototype)
return ret
}
}
// Result: function "extend"
解决方案
我会尝试使用Reflect.construct
这个:
let extend = function (constr) {
let ret;
if(Reflect && Reflect.construct){
ret = function(...args){
let inst = Reflect.construct(constr, args, eval('new.target'));
return inst;
}
} else {
ret = function () {
constr.apply(this, arguments)
}
}
ret.prototype = Object.create(constr.prototype);
ret.prototype.constructor = ret;
return ret;
}
该eval
行只是使您在将其转换为 ES5 时不会出现语法错误。如果你想扩展你创建的构造函数,这是必要的,extend
否则原型将会丢失。
推荐阅读
- typo3-9.x - 调用未定义的方法 Guzzle\Http\Client::request()
- node.js - 获取过去消息的功能停止工作。有什么办法解决吗?
- java - 当我什至不使用参数化测试时,为什么会出现 ParameterResolutionException?
- node.js - 我在安装 npm 时遇到问题,并且损坏了所有内容
- flutter - Flutter:将默认值从另一个 textformfield 设置为 textformfield
- javascript - 如何解决错误:不是函数(代码重构)
- python - 使用 selenium 抓取错误连接已关闭
- java - 如何根据长度替换单词?
- docker - Docker compose with Traefik 结果为 404
- elasticsearch - 我怎样才能为这个日志写一个 grok 模式?