Javascript 为什么文档引用变量比文档对象本身慢?

Javascript 为什么文档引用变量比文档对象本身慢?,javascript,Javascript,因为据说变量越接近正在运行的函数,它的性能就越好,所以我假设设置let doc=document和let win=window将比使用document或window对象本身(例如document.getElementById'id'vs doc.getElementById'id'执行得更好,或者至少相同。而且因为名字本身可以缩短,所以参考文献越短越好 然而,在我的测试中,参考比原始对象慢1.5倍。这背后有什么原因吗?由于浏览器假定这些常用的基本对象会被大量使用,所以“更近范围”规则是否不适用于

因为据说变量越接近正在运行的函数,它的性能就越好,所以我假设设置let doc=document和let win=window将比使用document或window对象本身(例如document.getElementById'id'vs doc.getElementById'id'执行得更好,或者至少相同。而且因为名字本身可以缩短,所以参考文献越短越好

然而,在我的测试中,参考比原始对象慢1.5倍。这背后有什么原因吗?由于浏览器假定这些常用的基本对象会被大量使用,所以“更近范围”规则是否不适用于这些基本对象

快速基准:

let doc, f1, f2;

doc = document;

f1 = function() {
    for (let i = 0; i < 10; i++) document.body;
    for (let i = 0; i < 10; i++) document.head;
    for (let i = 0; i < 10; i++) document.getElementsByTagName('body');
};

f2 = function() {
    for (let i = 0; i < 10; i++) doc.body;
    for (let i = 0; i < 10; i++) doc.head;
    for (let i = 0; i < 10; i++) doc.getElementsByTagName('body');
};

for (let j = 0; j < 3; j++) {
    console.time(1);
    for (let i = 0; i < 1000000; i++) f1();
    console.timeEnd(1);

    console.time(2);
    for (let i = 0; i < 1000000; i++) f2();
    console.timeEnd(2);
}

/*
Results:
1: 1162ms
2: 1687ms
1: 1096ms
2: 1648ms
1: 1079ms
2: 1644ms
*/

FWIW,在Chrome中,本地用户明显胜过全球用户,而非本地用户则更快:

循环=100000 函数testloops,fn,arg{ var t=新日期; while循环-fnarg; console.lognew Date-t; } 函数全局{ testLOOPS,=>window.outerHeight; } 局部函数{ var win=窗口; testLOOPS,=>win.outerHeight; } var win2=窗口; 函数非局部{ testLOOPS,=>win2.outerHeight; } 函数arg{ var win3=窗口; testLOOPS,x=>x.outerHeight,win3; } 全球的 地方的 非本地
arg显示您的基准测试设置。很可能时间安排不正确。我认为您忘记了声明额外变量的成本。1您的整个问题基于错误的信息。变量和使用它的函数之间的代码行距离与性能完全无关。好吧,除了在某些情况下,它使变量在内存中保持较长的时间,并且只有当内存变低时,它才会影响性能,但是在这种情况下,代码有更大的问题需要处理。2您的示例如何使变量更接近?功能在哪里?3尽管可以忽略不计,但声明新变量需要花费一定的成本。4没有一个是1.5倍,所以基准测试不正确。@RacilHilan:OP可能是指原型链中的距离。在主帖子中添加了快速基准测试。对我来说,所有3个测试都是~20-22。谷歌Chrome赢得10分。我建议将迭代次数至少增加10倍。得到一些更重要的数字。有趣的是,这里我也得到了localWin作为更快的函数,虽然我没有得到这么大的差异-平均值30表示全局,27表示局部。你所说的非局部实际上也是全局的。此外,你的结果也没有真正意义,类似于OP的1.5倍。正如@Cerbrus所提到的,结果应该更加接近。我已经在3个浏览器中进行了测试,得到了非常接近的结果。首先,我不认为这是一个减少成员级别的好例子,因为它实际上在一个级别上使用完全相同的级别。使用窗口和变量之间的差异可能是由于浏览器的引擎JS优化,类似于压缩JS,它压缩变量名而不是窗口。在特定测试中,局部变量和全局非局部变量之间不应存在任何可测量的差异,因为它们都在函数之外,并且在打印结果时仍在范围内。