Vytvoření vlastního prvku bez použití klíčového slova class

Toto je ve skutečnosti spíše otázka o modelu objektové orientace v ES6. Nicméně jako příklad použiji vytvoření nového vlastního prvku.

Takže nová a nablýskaná (dnes) metoda k vytvoření nového vlastního prvku je přes customElements.define() které obsahují značku name , constructor a options (což je volitelné) podle MDN, Google a samozřejmě spec. Veškerá uvedená dokumentace používá variaci nového class klíčové slovo pro constructor .

Za předpokladu, že se mi nelíbí nový class syntaxe a z větší části zvažující class je syntatický cukr (podle tohoto návodu). Specifikace dokonce konkrétně uvádí, že

Volání super() bez parametrů musí být prvním příkazem v těle konstruktoru, aby se vytvořil správný řetězec prototypu a tato hodnota před spuštěním jakéhokoli dalšího kódu.

Když jsem si přečetl tutoriál, přišel jsem s tím, abych vyzkoušel, zda je to možné (také revidovat a znovu se naučit objektový model Javascriptu).

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'));

Zobrazuje se mi tato chyba

Chyba:Vlastní prvek, který se vytváří, nebyl zaregistrován s customElements .

Moje otázka tedy zní, je možné to udělat bez použití class klíčové slovo (také bez new Pokud možno)? Pokud je odpověď ne, mám se držet class klíčové slovo namísto použití Object.create když v budoucnu napíšu nový kód Javascript?

Odpověď

V některých jednoduchých situacích je možné definovat vlastní prvek bez class klíčové slovo.

Trik je v použití Reflect.construct() nahradit super() zavolejte.

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 )

Všimněte si, že to není podporovaná syntaxe, protože, jak jste uvedli, třídy ES6 jsou trochu víc než jen syntaxický cukr.