【问题标题】:Creating custom element without using class keyword不使用 class 关键字创建自定义元素
【发布时间】:2018-02-14 17:41:54
【问题描述】:

这其实更多是关于 ES6 中面向对象模型的问题。不过,我将以创建新的自定义元素为例。

因此,创建新自定义元素的新的和闪亮的(截至今天)方法是通过customElements.define(),它接受标签nameconstructoroptions(可选)根据MDNGoogle,当然还有spec。列出的所有文档都使用了 constructor 的新 class 关键字的变体。

假设我不喜欢新的class 语法,并且考虑到大部分class 是一种语法糖(根据this tutorial)。规范甚至明确指出

super() 的无参数调用必须是 构造函数体,建立正确的原型链和this 运行任何其他代码之前的值。

通过阅读教程,我想出了这个来尝试是否可能(同时修改和重新学习 Javascript 的对象模型)。

var _extends = function(_parent) {
    var _result = function() {
        _parent.call(this);
    };
    _result.prototype = Object.create(_parent.prototype);
    Object.defineProperty(_result.constructor, 'constructor', {
        enumerable: false,
        writeable: true,
        value: _result
    });

    return _result;
};

customElements.define('foo-bar', _extends(HTMLElement));
console.log(document.createElement('foo-bar'));

我收到了这个错误

错误:正在构造的自定义元素未注册 customElements.

所以我的问题是,是否可以不使用 class 关键字(如果可能,也可以不使用 new)来做到这一点?如果答案是否定的,我以后写新的 Javascript 代码时是否应该坚持使用class 关键字而不是使用Object.create

【问题讨论】:

    标签: javascript web-component es6-class custom-element


    【解决方案1】:

    在一些简单的情况下,可以在没有class 关键字的情况下定义自定义元素。

    诀窍是使用Reflect.construct() 替换super() 调用。

    var CEo = function ()
    {
        console.log( "created" )
        return Reflect.construct( HTMLElement, [], CEo )
    }
    
    CEo.prototype = Object.create( HTMLElement.prototype )
    
    CEo.prototype.connectedCallback = function ()
    {
        console.log( "connected" )
        this.innerHTML = "Hello v1"
    } 
    
    customElements.define( "object-v1", CEo )
    

    请注意,它是不受支持的语法,因为正如您所说,ES6 类不仅仅是语法糖。

    【讨论】:

    • 大声笑,很高兴知道。不,不会那样做,我不想向未来的合作者解释为什么它会以这种方式工作。猜猜从现在开始我只写class以避免混淆。
    • 起初我尝试使用 Object 而不是 class 来定义自定义元素,但最后我不得不切换到 class...
    • 这促使我返回并在 javascript 中修改/重新学习对象模型):
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2019-09-23
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    相关资源
    最近更新 更多