2010-11-16 71 views
8

我知道如何添加新的方法对每个对象 - 通过扩大对象的原型:增加DOM元素节点的原型?

Object.prototype.foo = function() { }; 

但是,是可以定义为仅DOM元素节点的新方法? DOM元素节点对象是否有原型?或者是否有一般DOM节点的原型?

或者原型对象只存在于内置对象吗?

回答

20

是的,但不是在所有浏览器中。 Internet Explorer 8支持DOM原型(在某种程度上),Firefox,Chrome,Opera和Safari也是如此。

HTMLElement.prototype.toggle = function() { 
    this.style.display = this.style.display == 'none' ? '' : 'none'; 
} 

许多人认为通过原型扩展DOM对象是一种不好的做法。 Kangax在这方面有一篇很棒的文章:http://perfectionkills.com/whats-wrong-with-extending-the-dom/。然而,DOM原型允许我们在尚不支持它们的环境中实现基于标准的方法,就像ECMAScript第5版方法的垫片一样。

+0

这确实是一篇很棒的文章。我会检查出来并报告。 – 2010-11-16 12:04:02

+4

示例原型不隐藏元素。这是切换 – jscripter 2015-07-01 17:40:33

+0

为什么只是'HTMLDivElement'为什么不添加一个原型到所有的HTML元素? – vsync 2017-06-08 08:47:49

0

这正是prototype.js所做的,但现在被认为是非常糟糕的做法。 使用包装器/处理程序要好得多。请注意,增加任何本机对象,尤其是对象,是不好的做法。

读:

Whats wrong with extending the DOM
Object.prototype is verboten

附录:

虽然在延长小项目原生对象也算是安全它实际上将成为一个极坏的习惯中。在用功能和变量抛弃全球范围的情况下,它只会稍微更坏一点。不仅会发生名称冲突,还会发生实施冲突。混合起来的库越多,这种情况就会变得更加激烈。

将您的实现保留在您自己的对象上是避免任何冲突,名称,实现或其他方式的唯一方法。所有这些说法,你可以随心所欲地去做,但我不会推荐任何被广泛接受为纯粹不良做法的东西。我坚持我的建议。

+0

@BGerrissen你能解释一下prototype.js究竟做了什么吗?我对这个图书馆不熟悉。另外,你能否详细说明使用包装器/处理程序 - 你是什么意思?另外,你说“增加任何nativ对象,特别是Object对象” - 但我不是扩充它,而是它的原型对象。 – 2010-11-16 12:01:18

+6

推荐增加任何本地对象是恐惧mongering,国际海事组织。 * String.prototype *扩展是非常有用的,例如,唯一的潜在缺点是命名未来的冲突。 – 2010-11-16 12:06:30

+0

a)这是面向对象的本质,b)JS完全是面向对象的。从什么时候“现在”? – 2010-11-16 12:11:24

3

在一些浏览器中,DOM元素确实暴露了一个原型对象,该对象也可能继承自Object.prototype,但这不是普遍正确的(例如,IE不)。一般来说,DOM元素等主机对象不一定要这样做;事实上,宿主对象并不受适用于本地JavaScript对象的许多规则的束缚,所以你不应该依赖DOM元素来支持这种事情。我们推荐kangax's excellent article on this subject

+0

@Tim我问这个问题,因为我想让你的选择功能更方便。例如,如果我可以将一个'selec'对象添加到HTML元素节点,那么我可以使用如下的函数:'input.selec.get(); input.selec.set(5,8);' – 2010-11-16 12:08:50

+1

@Šime:啊,对。如果你使用jQuery,你可以像插件那样通过增加'$ .fn'来做类似的事情。否则,在没有某种元素包装对象(如jQuery)的情况下,这是不可能的。 – 2010-11-16 12:13:43

+0

对我们来说幸运的是,IE终于朝着正确的方向前进 - IE 9的DOM对象继承自Object.prototype。目前,Šime包装几乎肯定是最好的选择。 – 2010-11-16 12:18:57