请参阅http://jsperf.com/in-vs-member-object-access
基本上,为什么检查if ('bar' in foo) {}
明显慢于if (foo.bar !== undefined) {}
?
答案 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 foo
比foo.bar
慢。
in
速度不快的唯一原因是它没有得到JIT工程师那么多的关注,而是更常见的foo.bar
语法。
特别是在jsperf测试中, 属性作为foo
本身(不是原型)的直接属性存在,可以理所当然{{1}不应该比'bar' in foo
慢。如果有的话,它应该更快。两者之间的主要区别在于foo.bar !== undefined
可以在没有检查属性值的情况下得到解答!
在in
的情况下,我希望V8引擎和SpiderMonkey引擎都会检测到代码没有做任何有用的事情(也就是说,它没有可观察到的影响)并完全优化它。基准测试不测量任何实际工作。
显然,引擎还不够智能,无法优化foo.bar
,但这只是时间问题。和优先事项。