为什么JavaScript中的变量要慢得多

why are variables in javascript much slower?

本文关键字:变量 JavaScript 为什么      更新时间:2024-05-18
var completeObj = {a: { b: { c: { d: { e: { f: 23 } } } } } };
var funcA = function(obj){
    var a = 'a',b='b',c='c',d='d',e='e',f='f';
    return obj[a][b][c][d][e][f];
}
var funcB = function(obj){
    return obj['a']['b']['c']['d']['e']['f'];
}

funcA 比 funcB 慢得多,在范围内寻找变量需要花费这么多时间?测试网址 : http://jsperf.com/static-and-dynamic-argument感谢

http://jsperf.com/static-and-dynamic-argument/2

我拿了你的测试用例,并添加了一个测试用例来"证明一个观点"。当您通过['key']表示法访问对象中的某些内容时,您正在执行与通过.key访问它相同的操作。编译器足够聪明,知道['a']等同于.a。但是,当您将变量粘贴在那里时,正如Bergi在他的评论中提到的那样,编译器不知道[a]实际上是['a']

这是因为局部变量(函数范围(成为内部Variable对象的属性。因此,对 obj[a][b][c][d][e][f] 的调用最终会首先访问Variable对象上通过f a的属性,然后在completeObj上访问属性。

它与变量或变量范围无关(纯局部变量实际上是免费的(,而是使用反射来访问属性而不是常量。

obj['a']['b']['c']['d']['e']['f'];

等于 obj.a.b.c.d.e.f,因此即使从源代码中也知道将访问哪些属性。

但是,将

括号表示法与变量一起使用需要在运行时确定将访问哪些属性,因此完全不同。在Java中,前者代码类似于使用反射库访问属性,而后者与使用普通的静态点访问相同。


那么为什么编译器没有"意识到"变量也是静态的呢?好吧,你的代码是完全不合理的,JIT浪费时间优化不合理的代码是一个糟糕的JIT。

为什么它意识到['a'].a一样?好吧,至少根据我的经验,让解析器吐出相同的 MemberAccess 对象以进行点和括号访问,然后只检查表达式是否为常量字符串要简单得多。