在 Javascript 中向对象原型添加许多函数时出现性能问题?
我目前正在为许多不同的 Javascript 对象编写一个扩展方法库。例如,如果我向同一源文件中的不同对象(通过其原型)添加 200 多个方法,是否需要考虑性能?
编辑:仅供参考,我正在扩展内置对象。
I'm currently writing a library of extension methods to many different Javascript objects. Is there any performance considerations if, for example, i add over 200 methods to different objects (through their prototypes) in the same source file?
EDIT: Just for information, i'm extending the built-in objects.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不会,几乎不会对性能造成影响。即使将函数附加到原型也只需要几毫秒(也许 5 毫秒),超过这个时间,内存中的一个位置就会有 200 个函数,永远不会被复制,您永远不会注意到任何事情。当然,假设您要附加到某个东西的 .prototype 。
至于为什么没有速度影响:为了解析对象上的函数调用:
foo.doSomething()
,内部引擎需要遍历该对象的对象范围和原型链。基本上,它是这样做的:if(Object.hasOwnProperty('doSomething')){ // run Object.doSomething
if(Object.__proto__.hasOwnProperty('doSomething')){ // run Object.__proto__.doSomething
while(Object.__proto__.__proto__.__proto__.....){ //重复
每层都是一个哈希,所以查找时间是常数。 就查找速度而言,原型链中是否有 2 或 200 万个函数并不重要(尽管如果有 200 万个函数,您将消耗大量内存)。
供参考:jQuery 内部有 511 个函数。 200 根本不是那么多
旁注:不要扩展
Object.prototype
——只是不要。如果这样做,你就会破坏 for-in 循环,或者如果人们不使用显式的if(obj.hasOwnProperty(foo))
检查,至少会非常接近破坏它们。您还会使对象哈希上的 for-in 循环变慢,这是您在扩展原型时遇到的唯一潜在的减慢速度。请不要扩展 Array.prototype - 这让我很烦恼。但很多其他人都这样做,所以它并没有那么糟糕......争论是你不应该在数组上使用 for-in 循环,而且现在很多人不这样做因为 Prototype.js,但如果您愿意,您仍然应该被允许!
No, there will be almost no performance hit. Even attaching the functions to the prototype(s) should only take a few ms (maybe 5ms) and beyond that you have 200 functions sitting in memory in one spot, never being copied, you will never notice anything. Assuming, of course, that you are attaching to .prototype of something.
As for why there is no speed hit: In order to resolve a function call on an object:
foo.doSomething()
, the internal engine needs to walk the object scope and prototype chain of that object. Basically, it does this:if(Object.hasOwnProperty('doSomething')){ // run Object.doSomething
if(Object.__proto__.hasOwnProperty('doSomething')){ // run Object.__proto__.doSomething
while(Object.__proto__.__proto__.__proto__.....){ // repeat
Every layer of this is a hash, so lookups are constant time. In terms of lookup speed, it doesn't matter if there's 2 or 2 million functions in a prototype chain (Although if you have 2 million you'll be eating tons of memory).
For reference: jQuery has 511 functions internally. 200 isn't that many at all
Side note: DO NOT EXTEND
Object.prototype
-- JUST DON'T. You break for-in loops if you do this, or at least come very close to breaking them if people don't use explicitif(obj.hasOwnProperty(foo))
checks. You'll also make for-in loops slower on object hashes which is the ONLY potential slow-down you'll ever encounter extending prototypes.And PLEASE don't extend
Array.prototype
-- it annoys me. But plenty of other people do it, so it's not -as- bad... The argument is that you're not supposed to use for-in loops on Arrays, and many people now don't because of Prototype.js, but you should still be allowed to if you want to!