JavaScript 1.8.5(ECMAScript 5)添加了一些有趣的方法,这些方法可以防止以后以某种程度的彻底性修改传递的对象:
大概这些要点是捕捉错误:如果您知道不想在某个点之后修改对象,则可以将其锁定,以便在以后无意间修改它时会引发错误。("use strict";证明您已经做到了。)
我的问题:在使用V8之类的现代JS引擎中,使用上述方法锁定对象是否有任何性能优势(例如,更快的属性查找,减少的内存占用)?
(另请参阅John Resig的一个很好的解释-但是没有提到性能。)
JavaScript 1.8.5(ECMAScript 5)添加了一些有趣的方法,这些方法可以防止以后以某种程度的彻底性修改传递的对象:
大概这些要点是捕捉错误:如果您知道不想在某个点之后修改对象,则可以将其锁定,以便在以后无意间修改它时会引发错误。("use strict";证明您已经做到了。)
我的问题:在使用V8之类的现代JS引擎中,使用上述方法锁定对象是否有任何性能优势(例如,更快的属性查找,减少的内存占用)?
(另请参阅John Resig的一个很好的解释-但是没有提到性能。)
Answers:
还有的是没有什么区别,因为至少铬47.0.2526.80(64位)的性能。
Testing in Chrome 6.0.3359 on Mac OS 10.13.4
-----------------------------------------------
Test               Ops/sec
non-frozen object  106,825,468  ±1.08%  fastest
frozen object      106,176,323  ±1.04%  fastest
性能测试(可从http://jsperf.com/performance-frozen-object获得):
  const o1 = {a: 1};
  const o2 = {a: 1};
  Object.freeze(o2);
  // Non-frozen object:
  for(var key in o1);
  // Frozen object:
  for(var key in o2);
更新30.10.2019:Chrome 78.0.3904(64位)的性能没有差异
2019年9月17日更新:Chrome 76.0.3809(64位)的性能没有差异
更新03.05.2018:Chrome 66.0.3359(64位)的性能没有差异
更新06.03.2017:Chrome 56.0.2924(64位)的性能没有差异
2015年12月13日更新:Chrome 47.0.2526.80(64位)的性能没有差异
使用Chrome 34,在@pimvdb的测试用例中,冻结对象的性能要比未冻结对象好一些(结果如下)。但是,差异似乎还不足以证明使用此技术可获得性能上的好处。
http://jsperf.com/performance-frozen-object
Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  105,250,353  ±0.41%  3% slower
frozen object      108,188,527  ±0.55%  fastest
运行@kangax的测试用例表明,该对象的两个版本的性能几乎相同:
http://jsperf.com/performance-frozen-object-prop-access
Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  832,133,923  ±0.26%  fastest
frozen object      832,501,726  ±0.28%  fastest
http://jsperf.com/http-jsperf-com-performance-frozen-object-instanceof
Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  378,464,917  ±0.42%  fastest
frozen object      378,705,082  ±0.24%  fastest
something went wrong,您是否拥有为要求声明测试的代码的副本?
                    更新:自最初编写此答案以来,已解决了导致此问题的V8中的错误。有关更多信息,请参见Jan Molak的答案。
在Google Chrome浏览器(即V8)中,冻结对象的迭代速度比常规对象慢98%。
http://jsperf.com/performance-frozen-object
Test name*              ops/sec
non-frozen object    32,193,471
frozen object           592,726
可能是因为这些功能是相对较新的功能,可能尚未进行优化(但这只是我的猜测,老实说,我不知道原因)。
无论如何,我真的不建议将其用于性能上的好处,因为这显然没有意义。
*测试代码为:
var o1 = {a: 1};
var o2 = {a: 1};
Object.freeze(o2);
测试1(非冻结对象):
for(var key in o1);
测试2(冻结对象):
for(var key in o2);
Object.keys应慢一些。我同意它更像是一个错误,因为结霜不应该影响性能。相反。
                    从理论上讲,冻结对象可以使您对对象的形状做出更强有力的保证。
这意味着VM可以压缩内存大小。
这意味着VM可以优化原型链中的属性查找。
这意味着由于对象无法再更改,所有活动引用都变得不活动。
实际上,JavaScript引擎还没有进行这些积极的优化。
null。另一个是冻结整个原型链,以及Object.prototype(听起来很吓人)。
                    V8从2013年6月20日开始对Object.freeze进行了优化。从2014年12月10日开始,Object.seal和Object.preventExtensions进行了优化。请参见问题https://code.google.com/p/chromium/issues/detail?id= 115960
如果您对对象创建的性能(文字,冻结,密封Immutable.Map,密封)感兴趣,我已经在jsPerf上创建了一个测试来检查这一点。
到目前为止,我只有机会在Chrome 41和Firefox 37中对其进行测试。在这两种浏览器中,冻结或密封对象的创建时间比文字创建时间长三倍,而Immutable.Map性能要比文字创建时间长约50倍。文字。
我在生产代码中看到这些方法的唯一原因是,出于完整性目的,您可以具有密封或冻结的对象。
例如,我编写了一个小库,该库工作得很好,并在一个对象中为您提供了一组方法,但是我不想让您更改或覆盖我的任何属性或方法。我并不是说我可以阻止您这样做,但是我可以尝试防止您偶然地这样做,这也许更为重要。
而且,这些方法很容易在不知道它们的环境中“填充”,只需返回原始对象即可。那当然就没有效果了。
我看不到任何与性能相关的原因。