为什么javascript中的变量要慢得多?

时间:2013-12-09 06:14:36

标签: javascript google-chrome v8

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 THX

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

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

但是,对变量使用括号表示法需要在运行时确定将访问哪些属性,因此它们完全不同。在Java中,以前的代码就像使用Reflection库来访问属性,而后者与使用普通的静态点访问相同。


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

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

相关问题