扩展Object.prototype JavaScript

时间:2011-07-29 17:51:52

标签: javascript ecmascript-5

我不是在问这是否可以:

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

这几乎被所有人视为邪恶,因为它混淆了for(var i in obj)

真实问题

忽略

  • 不称职的浏览器(不支持Object.defineProperty的浏览器)
  • 财产碰撞或覆盖的可能性

假设你有一些令人难以置信的有用的方法,这被认为是错误的/不道德的吗?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});

如果你认为上述内容是不道德的,为什么他们甚至会首先实现这个功能呢?

5 个答案:

答案 0 :(得分:22)

我认为如果它适用于你的目标环境就好了。

此外,我认为原型扩展偏执狂被夸大了。只要你像一个好的开发者一样使用hasOwnProperty()就可以了。最糟糕的情况是,您在其他地方重载该属性并丢失该方法。但如果你这样做,那就是你自己的错。

答案 1 :(得分:11)

我会说这几乎和以前一样邪恶。与以前一样,最大的问题是 Object.prototype是全局的。虽然你的方法目前可能正在解决世界和平问题,但它可能会覆盖别人的方法(这可以保证银河的和平),或者将来可能会被一些你无法控制的图书馆覆盖(因此再次让世界陷入混乱)


新版本的Javascript具有许多与属性相关的功能,例如将属性定义为可枚举/不可枚举,具有getter和setter ... Object.defineProperty存在以控制此属性。

来自Mozilla Docs

  

此方法允许精确添加或修改属性   在一个对象上。通过赋值添加正常属性创建   属性枚举期间显示的属性(for ... in循环),   其值可能会更改,可能会被删除。这种方法   允许从默认值更改这些额外的详细信息。


这个新功能基本上是支持新功能所必需的,你应该在你自己的东西上使用它。能够修改Object.prototype只是它的一个副作用,它也是一个“正常”的对象,就像以前一样邪恶。

答案 2 :(得分:3)

在“JavaScript:好的部分”中,有一个类似的功能,我认为这对于改进javascript基础对象(如字符串,日期等等)非常有用,但仅限于此。

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}

答案 3 :(得分:3)

.hasOwnProperty()将通过继承属性排除迭代,我个人发现这些属性通常比有用更烦人。它在很大程度上打败了Object.create()的用处 - 这是具有讽刺意味的,因为说服每个人做.hasOwnProperty()的同一个人也提升了Object.create()

由于此处列出的原因,不应扩展Object.prototype。如果你真的想扩展它,那么使扩展不可迭代。

我意识到这面对所有已发布的最佳实践都是如此,但我们真的应该停止对对象密钥迭代“强制”.hasOwnProperty(),并接受直接对象到对象继承的有用性。 / p>

答案 4 :(得分:0)

简短的回答是,你应该这样做。

在此之前,需要采取一些预防措施:
1.在迭代对象时使用hasOwnProperty,但这并不是一个预防措施,在迭代对象时,我已经在使用hasOwnProperty了。 2.检查nameObject.prototype.name是否存在,避免名称冲突是非常安全的 3.利用Object.defineProperty(),只需添加额外的保护层。

如你所见,它并不复杂。

一旦你处理了风险/劣势,现在就有了优势:
1.方法链接,这只会使代码更具可读性,简洁性,并使编码更加愉快。反过来让你更快乐,让你的生活更轻松 2.解决浏览器兼容性问题,无论如何你都在进行polyfill。

P.S。: 在与大型团队合作时,不要这样做。