owerride原生javascript原型,对表演有好有坏吗?

时间:2018-03-20 09:27:28

标签: javascript performance override prototype

我知道为原型添加功能并不会花费更多的内存使用,原型会分享到所有实例。对内存这么好,但是,创建实例的全球时间呢?如果函数的索引更大,那么在每个新对象的加载函数索引花费的时间更长,不是吗?

在Object原型中添加很多功能,会降低全局性能吗?

例如,如果我想直接在Object或Array的原型中添加http://underscorejs.org lib的所有函数,则写myObject.where(...)而不是_.where(myObject, ...)
这是好还是坏的做法?

2 个答案:

答案 0 :(得分:2)

  

对内存这么好,但是,创建实例的全球时间呢?如果函数的索引更大,那么在每个新对象的加载函数索引花费的时间更长,不是吗?

没有。创建新实例时,它没有获得其原型上所有内容的副本,它会获得对其原型的引用。因此,其原型上的属性数量对创建实例所需的时间没有任何影响。

也就是说,我们在内存中开始(在全局初始化时)这样的事情(忽略了很多细节):

                 +−−−−−−−−−−−−+          
Object−−−−−−−−−−>| (function) |          
                 +−−−−−−−−−−−−+          +−−−−−−−−−−−−−−−−+
                 | prototype  |−−−−−−−−−>|    (object)    |
                 +−−−−−−−−−−−−+          +−−−−−−−−−−−−−−−−+
                                         | hasOwnProperty |
                                         | toString       |
                                         | valueOf        |
                                         | ...            |
                                         +−−−−−−−−−−−−−−−−+

然后如果我们这样做:

var o = {};

......我们有这样的事情:

                 +−−−−−−−−−−−−+          
Object−−−−−−−−−−>| (function) |          
                 +−−−−−−−−−−−−+          +−−−−−−−−−−−−−−−−+
                 | prototype  |−−−−−+−−−>|    (object)    |
                 +−−−−−−−−−−−−+     |    +−−−−−−−−−−−−−−−−+
                                    |    | hasOwnProperty |
                                    |    | toString       |
                                    |    | valueOf        |
                                    |    | ...            |
                                    |    +−−−−−−−−−−−−−−−−+
                 +−−−−−−−−−−−−−−−+  |
o−−−−−−−−−−−−−−−>|   (object)    |  |
                 +−−−−−−−−−−−−−−−+  |
                 | [[Prototype]] |−−+
                 +−−−−−−−−−−−−−−−+
  

例如,如果我想在ObjectArray的原型中直接添加http://underscorejs.org lib的所有函数,则编写myObject.where(...)而不是_.where(myObject, ...)   这是好事还是坏事?

它的好坏实践是一个意见问题,因此对于SO来说是偏离主题的。有一些客观问题需要考虑:

  • 如果您这样做,则必须使新属性不可枚举(通过Object.definedPropety),以便它们不会显示在for-in和{{1 }};否则,你会打破很多事情。
  • 如果JavaScript获得标准Object.keys,则突然发生冲突。
  • 如果您使用的库接受具有可选功能的对象,其中一个恰好称为where,并且您将对象传递给该库,则库将假定where是一个它正在寻找。

答案 1 :(得分:-2)

与时间一样古老的辩论。性能方面,随着应用程序的扩展,使用基于类和其他原型继承方法会产生副作用。这会影响性能。此外,在经典继承情况下扩展原型意味着每个新实例都必须运行原型链来执行,从而降低性能。 Lodash和其他工具是很好的帮助者,但我尝试在生产中避免使用它们,而采用更有效的vanilla解决方案,而不依赖于更多deps来扩大代码库。工厂函数提供了扩展本机JS对象的替代方法,并且因为它们只是函数,所以执行不需要担心构建到原型。因此,您可以提升性能。此外,var profile = $(this).data('profile'); var citizens = $(this).data('citizens'); console.log(citizens); console.log(profile); var keys = $.map(citizens, function(value, key) { var r; if (value.id == 4) { r = value } return r; }); console.log(keys); var zxcv = Object.assign({}, keys); console.log(zxcv);的上下文更容易保留,当您忘记在类实例前面编写this时,您不必担心愚蠢的错误。 ES6引入了类,许多人在使用它们时有很多跳跃,而不会质疑潜在的瓶颈。这不是一个黑白场景。所有关于选择最适合您的项目需求的解决方案。