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

时间:2022-08-22 21:17:40

Can I safely extend Javascript builtin classes, like Array?

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

I.e. on which browsers/environments will the following not work:

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

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 个解决方案

#1


4  

Depends on your definition of "work".

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

There are three main issues with prototype extension.

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

  • it's global scope so there is name collision
  • 它是全局范围,因此存在名称冲突

  • If your adding enumerable properties it breaks for .. in
  • 如果您添加可枚举的属性,它会中断... in

  • Code is confusing to read, is this an ES5 feature or a custom library?
  • 代码令人困惑,这是一个ES5功能还是自定义库?

It will work as in, Array.prototype and Array are mutable so you can add the code and call the properties.

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

However:

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

The above is an example of it breaking for .. in. This is easily solved with

以上是打破...的例子。这很容易解决

Object.defineProperty(Array.prototype, "trolls", {  value: ...,  enumerable: false});

(ES5 only. Breaks in IE<9. can't be emulated in legacy engines)

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

or with

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

Personally I avoid automatically extending natives for these exact reasons. However I think it's perfectly acceptable to have a .extendNatives function in your library like pd.extendNatives

我个人避免出于这些原因自动扩展原生代。但是我认为在你的库中有一个.extendNatives函数是完全可以接受的,比如pd.extendNatives

#2


1  

Safely, not really - because you can't be sure you're the only one extending them, or that you're actually extending the correct methods (see Prototype - last time I checked, it was extending the builtin classes, which wreaked havoc on others scripts' expectations of the builtins' behavior). Modifying objects you don't own is a path to very tricky territory ("oh, but is this the actual built-in concat(), or did some other script change it behind our back?").

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

See e.g. this for a more detailed discussion: http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/

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

#1


4  

Depends on your definition of "work".

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

There are three main issues with prototype extension.

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

  • it's global scope so there is name collision
  • 它是全局范围,因此存在名称冲突

  • If your adding enumerable properties it breaks for .. in
  • 如果您添加可枚举的属性,它会中断... in

  • Code is confusing to read, is this an ES5 feature or a custom library?
  • 代码令人困惑,这是一个ES5功能还是自定义库?

It will work as in, Array.prototype and Array are mutable so you can add the code and call the properties.

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

However:

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

The above is an example of it breaking for .. in. This is easily solved with

以上是打破...的例子。这很容易解决

Object.defineProperty(Array.prototype, "trolls", {  value: ...,  enumerable: false});

(ES5 only. Breaks in IE<9. can't be emulated in legacy engines)

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

or with

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

Personally I avoid automatically extending natives for these exact reasons. However I think it's perfectly acceptable to have a .extendNatives function in your library like pd.extendNatives

我个人避免出于这些原因自动扩展原生代。但是我认为在你的库中有一个.extendNatives函数是完全可以接受的,比如pd.extendNatives

#2


1  

Safely, not really - because you can't be sure you're the only one extending them, or that you're actually extending the correct methods (see Prototype - last time I checked, it was extending the builtin classes, which wreaked havoc on others scripts' expectations of the builtins' behavior). Modifying objects you don't own is a path to very tricky territory ("oh, but is this the actual built-in concat(), or did some other script change it behind our back?").

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

See e.g. this for a more detailed discussion: http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/

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