替换DOM元素对象的__proto__

时间:2014-06-03 11:30:37

标签: javascript dom browser prototype polymer

所以基本上我想通过以下代码扩展某种类型的DOM元素:

var element = document.createElement("div");
var proto = Object.create(HTMLDivElement.prototype);
proto.newMethod = function() {console.log("Good.");};
proto.newConst = Math.PI / 2;
element.__proto__ = proto;

此代码适用于Chrome,Firefox和IE11(IE10未经过测试,但可能会有效),但我不确定它是否适用于JavaScript,以及它是否会在将来继续使用,因为无论如何这段代码是黑客攻击DOM元素,部分是在JavaScript之外。有人可以解释它是如何工作的吗?我不完全理解这一点,我需要知道这种方法是否健全。感谢。


好的,为了让事情更清楚,我知道我应该使用Object.create()来指定原型,但真正的问题是元素对象是特殊的,并且不可能这样做。上面的代码更像是一种解决方法,这就是我提出这个问题的原因。


Google的Polymer改变了__proto__个DOM对象(code, line 259):

function implement(element, definition) {
  if (Object.__proto__) {
    element.__proto__ = definition.prototype;
  } else {
    customMixin(element, definition.prototype, definition.native);
    element.__proto__ = definition.prototype;
  }
}

那么,我应该相信这种方法,因为Google会使用它吗?

1 个答案:

答案 0 :(得分:2)

来自Mozilla Developer Network

  

__ proto __ 属性已弃用,不应使用。应使用Object.getPrototypeOf代替 __ proto __ getter来确定对象的 [[Prototype]] 。强烈建议不要改变对象的 [[Prototype]] ,因为它非常慢,并且不可避免地减慢了现代JavaScript实现中后续执行的速度。但是,ES6中提供了Object.setPrototypeOf作为 __ proto __ setter的一个非常优选的替代方法。

一般来说,修改像Array,String甚至HTMLElement这样的原生原型是不好的做法,详细描述here,但是如果你控制当前上下文中的所有内容,你可以通过添加,修改原型来修改原型。你自己的风险,一些额外的功能,以实现你想要的。如果您可以保证您的代码与其他代码不冲突,并且性能足迹可以忽略不计,那么您可以自由选择路径。

你的方法:

SomeHTMLElementInstance.__proto__ = newPrototype;

// or a general case like:

SomeHTMLElementPrototypeConstructor.prototype.newMethod = function () {
    // Do something here
}

推荐方法:

var SomeElementWrapper = function (someParams) {
    this.container = document.createElement('SomeHTMLElement');
}

SomeElementWrapper.prototype.someMethod = function () {
    // Do something with this.container without modifying its prototype
}