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
- Code is confusing to read, is this an ES5 feature or a custom library?
它是全局范围,因此存在名称冲突
如果您添加可枚举的属性,它会中断... in
代码令人困惑,这是一个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
- Code is confusing to read, is this an ES5 feature or a custom library?
它是全局范围,因此存在名称冲突
如果您添加可枚举的属性,它会中断... in
代码令人困惑,这是一个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/