为什么Javascript的“in”运算符始终比undefined的严格成员比较慢?

时间:2012-12-13 18:51:14

标签: javascript

请参阅http://jsperf.com/in-vs-member-object-access

基本上,为什么检查if ('bar' in foo) {}明显慢于if (foo.bar !== undefined) {}

2 个答案:

答案 0 :(得分:5)

foo.bar !== undefined只检查这两个值,看它们是否匹配。

虽然'bar' in foo必须使用某种机制来遍历foo的属性,以查看其中是否有bar

这是一篇有趣的阅读来自Ecma-script

  

in运算符

     

ShiftExpression中的生产RelationalExpression:RelationalExpression评估如下:
  1.评估RelationalExpression   2.调用GetValue(结果(1))   3.评估ShiftExpression   4.调用GetValue(结果(3))   5.如果Result(4)不是对象,则抛出TypeError异常   6.调用ToString(结果(2))。
  7.使用参数Result(6)调用Result(4)的[[HasProperty]]方法   8.返回结果(7)。

     

严格不等于运算符(!==)

     

生产EqualityExpression:EqualityExpression!== RelationalExpression评估如下:
  1.评估EqualityExpression   2.调用GetValue(结果(1))   3.评估RelationalExpression   4.调用GetValue(结果(3))   5.执行比较结果(4)===结果(2)。 (见下文。)
  6.如果Result(5)为true,则返回false。否则,返回true。

答案 1 :(得分:4)

你是对的。 "bar" in foofoo.bar慢。

是没有意义的

in速度不快的唯一原因是它没有得到JIT工程师那么多的关注,而是更常见的foo.bar语法。

特别是在jsperf测试中, 属性作为foo本身(不是原型)的直接属性存在,可以理所当然{{1}不应该比'bar' in foo慢。如果有的话,它应该更快。两者之间的主要区别在于foo.bar !== undefined可以在没有检查属性值的情况下得到解答!

in的情况下,我希望V8引擎和SpiderMonkey引擎都会检测到代码没有做任何有用的事情(也就是说,它没有可观察到的影响)并完全优化它。基准测试不测量任何实际工作。

显然,引擎还不够智能,无法优化foo.bar,但这只是时间问题。和优先事项。