我可以安全地扩展内置类的javascript吗?

时间:2011-11-24 21:43:58

标签: javascript class

我可以安全地扩展Javascript内置类,例如Array吗?

即。以下哪些浏览器/环境不起作用:

Array.prototype.double = function() { return  this.concat(this); }
Array.twice = function(a) { return a.double(); }
Array.twice([1, 2, 3]) # => [1, 2, 3, 1, 2, 3]

2 个答案:

答案 0 :(得分:4)

取决于您对“工作”的定义。

原型扩展有三个主要问题。

  • 它的全局范围因此存在名称冲突
  • 如果您添加了可枚举的属性,则会中断for .. in
  • 代码难以阅读,这是ES5功能还是自定义库?

它将起作用,Array.prototypeArray是可变的,因此您可以添加代码并调用属性。

然而:

Array.prototype.trolls = 42;
for (var k in []) {
  alert(k === "trolls");
}

以上是打破for .. in的示例。

可以很容易地解决这个问题
Object.defineProperty(Array.prototype, "trolls", {
  value: ...,
  enumerable: false
});

(仅限ES5。IE中的中断<9。无法在旧版引擎中模拟)

for (var k in []) {
  if ([].hasOwnProperty(k)) {
    alert(k === "trolls");
  }
}

就我个人而言,出于这些原因,我避免自动扩展原生代。但是我认为在您的库中设置.extendNatives函数是完全可以接受的,例如pd.extendNatives

答案 1 :(得分:1)

安全,不是真的 - 因为你不能确定你是唯一一个扩展它们的人,或者你实际上正在扩展正确的方法(参见Prototype - 我上次检查时,它正在扩展内置类,这对其他剧本对内置行为的期望造成了严重破坏。修改你不拥有的对象是一条非常棘手的领域的路径(“哦,但这是实际的内置concat(),还是其他一些脚本在我们背后改变它?”)。

参见例如这是一个更详细的讨论:http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/