2017-09-06 85 views
3

這實際上更多的是關於ES6中面向對象模型的問題。不過,我將以創建一個新的自定義元素爲例。不使用class關鍵字創建自定義元素

因此,新的和有光澤的(如今天的)方法來創建一個新的自定義元件是通過根據MDNGooglecustomElements.define()其採取在標籤name,一個constructor,和options(其是可選的),當然spec。列出的所有文檔均使用class關鍵字constructor的變體。

假設我不喜歡新的class語法,並且考慮到大部分class是一種合成糖(根據this tutorial)。該規範甚至專門指出

A parameter-less call to super() must be the first statement in the constructor body, to establish the correct prototype chain and this value before any further code is run.

通過閱讀教程,我想出了這個嘗試,如果有可能(也修改和重新學習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')); 

我收到此錯誤

Error: The custom element being constructed was not registered with customElements .

所以我的問題是,是否有可能做到這一點,而無需使用class關鍵字(也沒有new如果可能的話)?如果答案是否定的,當我在將來編寫新的Javascript代碼時,我應該堅持使用class關鍵字而不是使用Object.create

回答

2

在一些簡單的情況下,可以定義一個不帶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班不僅僅是syntaxic糖多一點。

+0

大聲笑,這是很好的知道。 Nah,不會那樣做,我不想解釋爲什麼它以這種方式對未來的合作者有效。從現在開始猜測,我只寫了'class'以避免混淆。 – Jeffrey04

+0

起初我試圖用Object而不是class來定義自定義元素,但最後我不得不切換到類... – Supersharp

+1

這促使我回去修改/重新學習JavaScript中的對象模型): – Jeffrey04

相關問題