为什么不赞成修改JavaScript对象的原型?

col*_*ode 18 javascript monkeypatching

我在这里和那里看到一些关于修改JavaScript对象原型的不满意的评论?我个人不知道这可能是一个什么问题.例如,扩展Array对象以具有map和include方法或创建更强大的Date方法?

bjo*_*rnd 24

问题是可以在几个地方修改原型.例如,一个库会将map方法添加到Array的原型中,并且您自己的代码将添加相同的但具有其他目的.因此,一个实现将被打破.

  • 您希望开发人员了解JQuery或DoJo等大型库的所有内部结构和实现吗?我怀疑他们是否会在下一个版本的框架之前得到任何实现,他们不得不重新开始.图书馆和框架的重点在于您只需要知道如何使用它们. (8认同)
  • 在这方面,如果他们决定使用多个库并且不知道他们的代码中发生了什么,我觉得这是开发人员的错...但这确实回答了我的问题,谢谢. (2认同)

McK*_*yla 10

主要是因为命名空间冲突.我知道Prototype框架在保持其名称与本机包含的名称不同时存在许多问题.

为人们提供公用事业有两种主要方法..

原型

将函数添加到Object的原型中.MooTools和Prototype就是这样做的.

好处:

  1. 超级方便.

缺点:

  1. 可以使用很多系统内存.虽然现代浏览器只是从构造函数中获取属性的实例,但是一些较旧的浏览器为每个构造函数实例存储每个属性的单独实例.
  2. 不一定总是可用.

我的意思是"不可用"是这样的:

想象一下,你有一个NodeList document.getElementsByTagName,你想迭代它们.你做不到..

document.getElementsByTagName('p').map(function () { ... });
Run Code Online (Sandbox Code Playgroud)

..因为它是一个NodeList,而不是一个数组.上面会给你一个错误:Uncaught TypeError: [object NodeList] doesn't have method 'map'.

我应该注意,有很简单的方法可以将NodeList和其他类似Array的对象转换为实际数组.

搜集

在其上创建一个全新的全局变量和库存堆积实用程序.jQuery和Dojo这样做.

好处:

  1. 永远在那里.
  2. 内存使用率低.

缺点:

  1. 不是很好.
  2. 有时使用会感到尴尬.

用这种方法你仍然无法做到..

document.getElementsByTagName('p').map(function () { ... });
Run Code Online (Sandbox Code Playgroud)

..但你可以做..

jQuery.map(document.getElementsByTagName('p'), function () { ... });
Run Code Online (Sandbox Code Playgroud)

..但正如Matt所指出的那样,在通常的使用中,你会用上面的方法来做..

jQuery('p').map(function () { ... });
Run Code Online (Sandbox Code Playgroud)

哪个更好?

最终,这取决于你.如果您有被覆盖/覆盖的风险,那么我强烈建议进行原型设计.这是我喜欢的风格,我觉得风险值得结果.如果你对我不太满意,那么收藏也是一种很好的风格.它们都有优点和缺点,但总的来说,它们通常产生相同的最终结果.


rah*_*han 6

正如bjornd指出的那样,猴子修补只有在涉及多个库时才会出现问题.因此,如果您正在编写可重用的库,那么这不是一个好的做法.但是,在javascript中使用主机对象时,它仍然是解决跨浏览器兼容性问题的最佳技术.

当prototype.js和json2.js一起使用时,请查看此链接以了解真实事故.