I was working on an AJAX-enabled asp.net application. I've just added some methods to Array.prototype like
我正在开发一个支持ajax的asp.net应用程序。我刚刚添加了一些方法到数组中。像原型
Array.prototype.doSomething = function(){
...
}
This solution worked for me, being possible reuse code in a 'pretty' way.
这个解决方案对我起了作用,以一种“漂亮”的方式重用代码。
But when I've tested it working with the entire page, I had problems.. We had some custom ajax extenders, and they started to behave as the unexpected: some controls displayed 'undefined' around its content or value.
但是当我用整个页面测试它时,我遇到了问题。我们有一些定制的ajax扩展器,它们的行为开始变得出乎意料:一些控件在其内容或值周围显示“未定义”。
What could be the cause for that? Am I missing something about modifing the prototype of standart objects?
原因是什么呢?我是否遗漏了一些关于修改标准艺术品原型的东西?
Note: I'm pretty sure that the error begins when I modify the prototype for Array. It should be only compatible with IE.
注意:我确信当我修改数组的原型时,错误就开始了。它应该只与IE兼容。
5 个解决方案
#1
36
Modifying the built-in object prototypes can be a bad idea in general, because it always has the potential to * with other code on the same page.
一般来说,修改内置对象原型可能不是一个好主意,因为它总是有可能与同一页面上的其他代码发生冲突。
In the case of the Array object prototype, it is an especially bad idea, because it has the potential to interfere with any piece of code that iterates over the members of any array, for instance with for .. in
.
对于数组对象原型来说,这是一个特别糟糕的想法,因为它可能会干扰遍历任何数组成员的任何代码片段,例如for .。在。
To illustrate using an example (borrowed from here):
举例说明(从这里借用):
Array.prototype.foo = 1;
// somewhere deep in other javascript code...
var a = [1,2,3,4,5];
for (x in a){
// Now foo is a part of EVERY array and
// will show up here as a value of 'x'
}
It would be better for you to create your own type of object constructor complete with doSomething function, rather than extending the built-in Array.
您最好使用doSomething函数创建自己的对象构造函数类型,而不是扩展内置数组。
Edit: to repeat what I put in a comment:
编辑:重复我的评论:
The inverse is true - you should avoid for..in in case some n00b has modified the Array prototype, and you should avoid modifying the Array prototype in case some n00b has used for..in on an array. ;)
反过来是对的,你应该避免…如果某个n00b修改了数组原型,并且您应该避免修改数组原型,以防某个n00b使用了。在一个数组。,)
Also, there now exists Object.defineProperty
as a general way of extending object prototypes without the new properties being enumerable, though I still wouldn't use this as justification for extending the built-in types, because even besides for..in
there is still the potential for other conflicts with other scripts. Consider someone forking your code and then putting both versions on the same page - will your custom enhancement to the Array object still work as you expect?
而且,现在有object . defineproperty作为一种扩展对象原型的通用方法,而没有对新属性进行可枚举,尽管我仍然不会用它作为扩展内置类型的理由,因为…仍然存在与其他脚本发生冲突的可能性。假设有人为您的代码分叉,然后将两个版本放在同一个页面上—您对Array对象的自定义增强是否仍然像您期望的那样工作?
#2
27
While the potential for *ing with other bits o' code the override a function on a prototype is still a risk, if you want to do this with modern versions of JavaScript, you can use the Object.defineProperty method, turning off the enumerable bit, e.g.
虽然在原型上重写函数可能会与其他位代码发生冲突,但这仍然是一个风险,如果您希望使用现代版本的JavaScript来实现这一点,您可以使用objec . defineproperty方法,关闭可枚举位,例如。
// functional sort
Object.defineProperty(Array.prototype, 'sortf', {
enumerable: false,
value: function(compare) { return [].concat(this).sort(compare); }
});
#3
9
There is a caution! Maybe you did that: fiddle demo
有一个警告!也许你做了,小提琴演示。
Let us say an array and a method foo which return first element:
假设一个数组和一个方法foo返回第一个元素:
var myArray = ["apple","ball","cat"];
foo(myArray) // <- 'apple'
function foo(array){
return array[0]
}
The above is okay because the functions are uplifted to the top during interpretation time.
以上是可以的,因为函数在解释时间被提升到顶部。
But, this DOES NOT work: (Because the prototype is not definned)
但是,这是行不通的(因为原型没有被定义)
myArray.foo() // <- 'undefined function foo'
Array.prototype.foo = function(){
return this[0]
}
For this to work, simply define prototypes at the top:
要实现这一点,只需在顶部定义原型:
Array.prototype.foo = function(){
return this[0]
}
myArray.foo() // <- 'apple'
And YES! You can override prototypes!!! It is ALLOWED. You can even define your own own
add
method for Arrays.是的!你可以覆盖原型! ! !它是被允许的。甚至可以为数组定义自己的添加方法。
#4
1
In general messing with the core javascript objects is a bad idea. You never know what any third party libraries might be expecting and changing the core objects in javascript changes them for everything.
一般来说,搞乱核心javascript对象是一个坏主意。您永远不知道任何第三方库可能期望什么,并且更改javascript中的核心对象会更改它们。
If you use Prototype it's especially bad because prototype messes with the global scope as well and it's hard to tell if you are going to collide or not. Actually modifying core parts of any language is usually a bad idea even in javascript.
如果你使用Prototype,那就很糟糕了,因为Prototype也会影响全局范围,很难判断是否会发生冲突。实际上,修改任何语言的核心部分通常都不是一个好主意,即使在javascript中也是如此。
(lisp might be the small exception there)
(lisp可能是一个很小的例外)
#5
1
You augmented generic types so to speak. You've probably overwritten some other lib's functionality and that's why it stopped working.
可以这样说,您扩充了泛型类型。您可能已经覆盖了其他一些lib的功能,这就是它停止工作的原因。
Suppose that some lib you're using extends Array with function Array.remove(). After the lib has loaded, you also add remove() to Array's prototype but with your own functionality. When lib will call your function it will probably work in a different way as expected and break it's execution... That's what's happening here.
假设您正在使用的一些lib扩展数组具有函数Array.remove()。在lib加载之后,您还可以向Array的原型添加remove(),但是要使用自己的功能。当lib调用你的函数时,它可能会以不同的方式工作,并中断它的执行……这里发生了什么。
#1
36
Modifying the built-in object prototypes can be a bad idea in general, because it always has the potential to * with other code on the same page.
一般来说,修改内置对象原型可能不是一个好主意,因为它总是有可能与同一页面上的其他代码发生冲突。
In the case of the Array object prototype, it is an especially bad idea, because it has the potential to interfere with any piece of code that iterates over the members of any array, for instance with for .. in
.
对于数组对象原型来说,这是一个特别糟糕的想法,因为它可能会干扰遍历任何数组成员的任何代码片段,例如for .。在。
To illustrate using an example (borrowed from here):
举例说明(从这里借用):
Array.prototype.foo = 1;
// somewhere deep in other javascript code...
var a = [1,2,3,4,5];
for (x in a){
// Now foo is a part of EVERY array and
// will show up here as a value of 'x'
}
It would be better for you to create your own type of object constructor complete with doSomething function, rather than extending the built-in Array.
您最好使用doSomething函数创建自己的对象构造函数类型,而不是扩展内置数组。
Edit: to repeat what I put in a comment:
编辑:重复我的评论:
The inverse is true - you should avoid for..in in case some n00b has modified the Array prototype, and you should avoid modifying the Array prototype in case some n00b has used for..in on an array. ;)
反过来是对的,你应该避免…如果某个n00b修改了数组原型,并且您应该避免修改数组原型,以防某个n00b使用了。在一个数组。,)
Also, there now exists Object.defineProperty
as a general way of extending object prototypes without the new properties being enumerable, though I still wouldn't use this as justification for extending the built-in types, because even besides for..in
there is still the potential for other conflicts with other scripts. Consider someone forking your code and then putting both versions on the same page - will your custom enhancement to the Array object still work as you expect?
而且,现在有object . defineproperty作为一种扩展对象原型的通用方法,而没有对新属性进行可枚举,尽管我仍然不会用它作为扩展内置类型的理由,因为…仍然存在与其他脚本发生冲突的可能性。假设有人为您的代码分叉,然后将两个版本放在同一个页面上—您对Array对象的自定义增强是否仍然像您期望的那样工作?
#2
27
While the potential for *ing with other bits o' code the override a function on a prototype is still a risk, if you want to do this with modern versions of JavaScript, you can use the Object.defineProperty method, turning off the enumerable bit, e.g.
虽然在原型上重写函数可能会与其他位代码发生冲突,但这仍然是一个风险,如果您希望使用现代版本的JavaScript来实现这一点,您可以使用objec . defineproperty方法,关闭可枚举位,例如。
// functional sort
Object.defineProperty(Array.prototype, 'sortf', {
enumerable: false,
value: function(compare) { return [].concat(this).sort(compare); }
});
#3
9
There is a caution! Maybe you did that: fiddle demo
有一个警告!也许你做了,小提琴演示。
Let us say an array and a method foo which return first element:
假设一个数组和一个方法foo返回第一个元素:
var myArray = ["apple","ball","cat"];
foo(myArray) // <- 'apple'
function foo(array){
return array[0]
}
The above is okay because the functions are uplifted to the top during interpretation time.
以上是可以的,因为函数在解释时间被提升到顶部。
But, this DOES NOT work: (Because the prototype is not definned)
但是,这是行不通的(因为原型没有被定义)
myArray.foo() // <- 'undefined function foo'
Array.prototype.foo = function(){
return this[0]
}
For this to work, simply define prototypes at the top:
要实现这一点,只需在顶部定义原型:
Array.prototype.foo = function(){
return this[0]
}
myArray.foo() // <- 'apple'
And YES! You can override prototypes!!! It is ALLOWED. You can even define your own own
add
method for Arrays.是的!你可以覆盖原型! ! !它是被允许的。甚至可以为数组定义自己的添加方法。
#4
1
In general messing with the core javascript objects is a bad idea. You never know what any third party libraries might be expecting and changing the core objects in javascript changes them for everything.
一般来说,搞乱核心javascript对象是一个坏主意。您永远不知道任何第三方库可能期望什么,并且更改javascript中的核心对象会更改它们。
If you use Prototype it's especially bad because prototype messes with the global scope as well and it's hard to tell if you are going to collide or not. Actually modifying core parts of any language is usually a bad idea even in javascript.
如果你使用Prototype,那就很糟糕了,因为Prototype也会影响全局范围,很难判断是否会发生冲突。实际上,修改任何语言的核心部分通常都不是一个好主意,即使在javascript中也是如此。
(lisp might be the small exception there)
(lisp可能是一个很小的例外)
#5
1
You augmented generic types so to speak. You've probably overwritten some other lib's functionality and that's why it stopped working.
可以这样说,您扩充了泛型类型。您可能已经覆盖了其他一些lib的功能,这就是它停止工作的原因。
Suppose that some lib you're using extends Array with function Array.remove(). After the lib has loaded, you also add remove() to Array's prototype but with your own functionality. When lib will call your function it will probably work in a different way as expected and break it's execution... That's what's happening here.
假设您正在使用的一些lib扩展数组具有函数Array.remove()。在lib加载之后,您还可以向Array的原型添加remove(),但是要使用自己的功能。当lib调用你的函数时,它可能会以不同的方式工作,并中断它的执行……这里发生了什么。