在Javascript中向Object.prototype添加方法的好处和危险是什么?

在Javascript中向Object.prototype添加方法的好处和危险是什么?,javascript,prototype,Javascript,Prototype,我知道这在五年前是一个有争议的问题,但我想知道,对于今天的JavaScript,情况是否发生了变化。在现实世界中,是否有任何大型现代库与扩展对象prototype不兼容的例子 我对假设的“有人可能会在你将来想要使用的库中编写糟糕的迭代代码,然后你可能会得到一个奇怪的bug”不感兴趣 是否有任何现实世界中的大型现代库与扩展Object.prototype不兼容的例子 是的,我记得jQuery的问题,它是侵入性较小的库之一,例如: Object.defineProperty(Object.proto

我知道这在五年前是一个有争议的问题,但我想知道,对于今天的JavaScript,情况是否发生了变化。在现实世界中,是否有任何大型现代库与扩展
对象prototype
不兼容的例子

我对假设的“有人可能会在你将来想要使用的库中编写糟糕的
迭代代码,然后你可能会得到一个奇怪的bug”不感兴趣

是否有任何现实世界中的大型现代库与扩展Object.prototype不兼容的例子

是的,我记得jQuery的问题,它是侵入性较小的库之一,例如:

Object.defineProperty(Object.prototype, 'foo', { value: 'bar' });
我记得的另一个例子是,有人向
对象.prototype
对象添加了
load
函数,它导致
$()事件出现问题。load
事件:

// DON'T DO THIS ! :)
Object.prototype.load = function () {};

​$(window).load(function () {
  alert('load event'); // never fired
});​
例如

决不建议以这种方式扩充
对象.prototype
对象,因为这些属性将被大量对象(甚至是某些宿主对象)继承,而且正如您所知,主要问题是它们将由
for in
语句枚举

在ECMAScript 5中,现在存在一种更安全的方法,因为我们现在可以声明不可枚举的属性,例如:

Object.defineProperty(Object.prototype, 'foo', { value: 'bar' });
在属性描述符-
{value:'bar'}
-中,我们可以指定属性属性,在上面示例中的值属性的情况下,我们可以指定
可写的
属性和公共的
可配置的
属性(确定是否可以重新配置属性-属性更改-或删除)

我们还有
enumerable
属性,它确定属性是否将由
for in
语句枚举

如果我们不指定属性,默认情况下它们是
false
,描述符将如下所示:

{
  value: 'bar',
  writable: false,
  configurable: false,
  enumerable: false
}

关于这一点,我们有一个很好的讨论,感谢关于jQuery在扩展Object.prototype时在所有情况下都不能正常工作的信息。我已经读到他们计划在将来的某个时候让它能够很好地交互。我想现在在没有仔细考虑的情况下扩展Object.prototype还为时过早oooo获取额外信息;我在对象原型中添加了两个扩展(forEach和getLength),它打破了大多数google脚本。