2024年Clojure调查中分享您的想法!

欢迎!请访问关于页面以了解更多关于此页面的信息。

+2
ClojureScript

支持生成ES6类

ES6为JavaScript引入了类语法。在最近版本之前,周围的许多工作都使用polyfills完成,但随着浏览器的进步,越来越多的库开始本地使用此功能,这带来了一定的麻烦。通过“黑客”方式获取类,你可以总是从子类调用原始构造函数,但与原生的ES6类不同。为了展示这个问题,让我们看看JS中的一个简单的类扩展示例:

`
class A {
constructor(x) {

this.x = x;

}
}

class B extends A {
constructor(foo) {

super(foo);

}
}
`

尝试不使用类来复制此方法可以这样做:

`
function B(foo) {
A.prototype.constructor.call(this, foo);
}

Reflect.setPrototypeOf(B.prototype, A.prototype)
`

但尝试使用new B("bar")调用这个新构造函数会触发浏览器异常:Uncaught TypeError: Class constructor A cannot be invoked without 'new'

根本问题是构造函数不能以函数的形式调用,这限制了ClojureScript的功能,因为它阻止了直接扩展这些类的功能,而必须回退到常规JS来处理这些情况。

因此,这似乎需要一个方法来从Clojurescript生成实际的ES6类(也许是一个defclass宏?)。

本探索中使用的资源

https://rete.js.org - 使用原生类的一个库,依赖于其用法
https://esdiscuss.org/topic/extending-an-es6-class-using-es5-syntax - 关于使用ES5模拟ES6类的讨论
https://medium.com/@robertgrosse/how-es6-classes-really-work-and-how-to-build-your-own-fd6085eb326a - 关于类如何工作的更多文档

但所有这些资源似乎都处理了一个原生类尚未存在的时间,因此它们不必处理原生构造函数调用。

3 答案

0

评论由:dnolen发布

我们可能需要一个设计页面来详细列出选项和权衡,这个任务必须完成之后,这个工单才会继续进行。

0

评论者:filipematossilva

有方法可以生成具有扩展功能的ES5构造函数,其行为类似于ES2015类。TypeScript就是一个很好的例子。

原始代码:

`
class A {
constructor(x) {

this.x = x;

}
}

class B extends A {
constructor(foo) {

super(foo);

}
}

const b = new B("bar")
`

转换为:

`
var extends = (this && this.extends) || (function ()

var extendStatics = function (d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return extendStatics(d, b);
};
return function (d, b) {
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

})();
var A = /* @class / (function ()

function A(x) {
    this.x = x;
}
return A;

}());
var B = /* @class / (function (_super) {

__extends(B, _super);
function B(foo) {
    return _super.call(this, foo) || this;
}
return B;

}(A));
var b = new B("bar");
`

这里的{{__extends}}是由TS生成的辅助工具,可以是内联的,或者从名为{{tslib}}的辅助库中导入。

因此,似乎没有必要在CLJS内部制造ES2015类。

0
参考资料:https://clojure.atlassian.net/browse/CLJS-3084(由wilkerlucio报告)
...