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") 调用这个新构造函数会触发浏览器异常:未捕获的TypeError: 类构造函数A无法在不使用'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
by

评论者: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
by
参考:[链接](https://clojure.atlassian.net/browse/CLJS-3084) (由wilkerlucio提出)
...