我正在研究启用AJAX的asp.net应用程序。我刚刚向Array.prototype添加了一些方法,例如
Array.prototype.doSomething = function(){ ... }
该解决方案对我有用,可以以“漂亮”的方式重用代码。
但是,当我测试了它与整个页面一起使用时,我遇到了问题。我们有了一些自定义的Ajax扩展程序,它们开始表现出意想不到的效果:某些控件在其内容或值上显示为“未定义”。
这可能是什么原因?我是否缺少修改标准对象原型的东西?
注意:我很确定,当我为Array修改原型时,错误就开始了。它应该仅与IE兼容。
通常,修改内置对象原型不是一个好主意,因为它总是有可能与其他供应商或加载在同一页面上的库的代码发生冲突。
在Array对象原型的情况下,这是一个特别糟糕的主意,因为它有可能干扰在任何数组的成员上迭代的任何代码段,例如使用for .. in。
for .. in
为了举例说明:
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' }
不幸的是,这样做的可疑代码的存在使得有必要也避免使用简单for..in的数组迭代,至少如果您想要最大的可移植性,只是为了防止其他一些令人讨厌的代码修改了Array原型的情况。因此,您确实需要同时做这两个事情:for..in如果某些n00b修改了Array原型,则应避免使用plain,并且应避免修改Array原型,以免弄乱任何使用plain for..in来遍历数组的代码。
for..in
您最好创建自己的带有doSomething函数的对象构造函数类型,而不是扩展内置Array。
那Object.defineProperty呢
Object.defineProperty
现在,存在Object.defineProperty一种扩展对象原型的通用方法,而无法枚举新属性,尽管这仍然不能证明扩展 内置 类型的合理性,因为即使如此for..in,它仍然可能与其他脚本发生冲突。考虑使用两个Javascript框架的人,它们都试图以相似的方式扩展Array并选择相同的方法名称。或者,考虑有人分叉 您的 代码,然后将原始版本和分叉版本都放在同一页面上。Array对象的自定义增强功能是否仍然有效?
这是Javascript的现实,也是为什么即使使用,也应该避免修改内置类型的原型的原因Object.defineProperty。用自己的构造函数定义自己的类型。