如何从DOM元素类继承

whe*_*hys 7 javascript inheritance dom

我想编写一些扩展DOM节点的Javascript类(这样我就可以直接将我的类的实例插入到DOM中),但是我很难找到我应该继承的类/原型.

例如:

function myExtendedElement() {
       this.superclass = ClassA;
       this.superclass();
       delete this.superclass;
} 
Run Code Online (Sandbox Code Playgroud)

但ClassA应该是什么?

kan*_*gax 20

这样做并不是一个好主意.

首先,要从DOM元素继承,您需要访问该元素的原型.问题是并非所有浏览器都提供对DOM元素原型的访问.例如,较新的Gecko和基于WebKit的客户端将这些原型中的一些暴露为全局对象--HTMLDivElement,HTMLElement,Element,Node等.

例如,普通DIV元素通常具有类似于以下内容的原型链:

HTMLDivElement.prototype -> HTMLElement.prototype -> Element.prototype 
  -> Node.prototype -> Object.prototype -> null
Run Code Online (Sandbox Code Playgroud)

您可以访问其中任何一个并根据需要扩展或继承.但是,即使你可以,我强烈建议不要.

当浏览器没有公开这些原型时,你几乎没有运气.您可以尝试通过以下constructorDOM元素本身的属性来检索它们-

document.createElement('div').constructor;
Run Code Online (Sandbox Code Playgroud)

- 但是不能保证元素具有constructor属性(例如IE6没有),即使它确实存在,该属性也引用"正确"对象.毕竟,如果构造函数确实引用了正确的对象,那么仍然无法保证允许对这些对象进行扩充.事实上,允许宿主对象实现完全奇怪的行为,甚至不必遵循原生JS对象遵循的规则(你可以在现实生活中找到几十个这样的例子).

你想避免继承DOM元素原型的第二个原因是这种继承的机制并没有真正指定在任何地方; 它可能是古怪的,不可预测的,整体脆弱和不可靠.

是的,你可以创建一个构造函数来初始化具有适当原型链的对象(即在其中包含DOM原型):

function MyDivElement(){}
MyDivElement.prototype = HTMLDivElement.prototype;

var myDiv = new MyDivElement();
typeof myDiv.appendChild; // "function"
Run Code Online (Sandbox Code Playgroud)

- 但这和它一样多,并且通过在原型中使用某些方法而没有其他任何东西来限制整个方法的有用性 -

typeof myDivElement.nodeName; // "undefined"
myDivElement.innerHTML = '<span>foo<\/span>';
myDivElement.childNodes; // Error
Run Code Online (Sandbox Code Playgroud)

直到某些标准规定了从DOM原型继承的确切机制(并且浏览器实际上实现了该机制),最好不要管它们,也许尝试其他方法 - 例如包装器或装饰器模式而不是原型:)

  • 这已经过时了.您可以使用自定义元素扩展DOM,这些元素是从HTMLElement继承所必需的; 至少自2013年以来一直在进行的工作https://www.w3.org/TR/custom-elements/ (2认同)