在javascript中,访问'window.Math'比没有'window'访问'Math'对象更慢或更快.

Mar*_*ers 5 javascript performance global window global-variables

我很好奇在javascript中引用"全局"命名空间时最佳实践是什么,这只是window对象的快捷方式(反之亦然,取决于你如何看待它).

我想知道是否:

var answer = Math.floor(value);
Run Code Online (Sandbox Code Playgroud)

是好还是坏:

var answer = window.Math.floor(value);
Run Code Online (Sandbox Code Playgroud)

性能,资源使用或兼容性是更好还是更差,甚至是轻微的?

是否有更轻微的成本?(像额外的指针或东西)

编辑注释:虽然在大多数情况下我对性能纳粹的可读性,但在这种情况下,我忽略了可读性的差异,只关注性能.

Bli*_*ixt 14

首先,出于性能原因,绝不要比较这些内容.Math.round在眼睛上显然比在眼睛上容易window.Math.round,并且通过使用其中一种,你不会看到明显的性能提升.所以不要混淆代码以获得非常轻微的性能提升.

但是,如果你只是想知道哪一个更快......我不确定全局范围是如何在"引擎盖下"查找的,但我猜想访问window与访问Math(windowMath生活在一起)相同同样的水平,如window.window.window.Math.round工作所证明的那样).因此,访问window.Math速度会变慢.

此外,查找变量的方式,您会看到通过执行var round = Math.round;和调用来提高性能round(1.23),因为所有名称首先在当前本地范围中查找,然后在当前范围内查找范围,依此类推,一直到全球范围.每个范围级别都会增加非常小的开销.

但是,除非你确定它们会产生显着的差异,否则不要做这些优化.可读,易懂的代码对于它现在和将来的工作方式都很重要.

这是使用Firebug的完整分析:

<!DOCTYPE html>
<html>
    <head>
        <title>Benchmark scope lookup</title>
    </head>
    <body>
        <script>
        function bench_window_Math_round() {
            for (var i = 0; i < 100000; i++) {
                window.Math.round(1.23);
            }
        }

        function bench_Math_round() {
            for (var i = 0; i < 100000; i++) {
                Math.round(1.23);
            }
        }

        function bench_round() {
            for (var i = 0, round = Math.round; i < 100000; i++) {
                round(1.23);
            }
        }

        console.log('Profiling will begin in 3 seconds...');
        setTimeout(function () {
            console.profile();
            for (var i = 0; i < 10; i++) {
                bench_window_Math_round();
                bench_Math_round();
                bench_round();
            }
            console.profileEnd();
        }, 3000);
        </script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

我的结果:
Time显示总计100,000*10个电话,Avg/ Min/ Max显示100,000个电话的时间.

Calls  Percent  Own Time   Time       Avg        Min        Max
bench_window_Math_round
10     86.36%   1114.73ms  1114.73ms  111.473ms  110.827ms  114.018ms   
bench_Math_round
10      8.21%    106.04ms   106.04ms   10.604ms   10.252ms   13.446ms   
bench_round
10      5.43%     70.08ms    70.08ms    7.008ms    6.884ms    7.092ms
Run Code Online (Sandbox Code Playgroud)

如你所见,这window.Math是一个非常糟糕的主意.我想访问全局window对象会增加额外的开销.但是,Math从全局范围访问对象和仅通过引用Math.round函数访问本地变量之间的区别并不是很大...请记住,这是100,000次调用,差异仅为3.6ms.即使有一百万个电话,你也只能看到36毫秒的差异.

使用上述分析代码需要考虑的事项:

  • 这些函数实际上是从另一个范围中查找的,这增加了开销(尽管我只是尝试将函数导入到匿名函数中).
  • 实际Math.round功能增加了开销(我估计在100,000次呼叫中大约6ms).