通过阅读Lodash的代码并了解它经常使用类型比较(在其_.is *工具套件中),我运行了一些测试以确认它更快,实际上它是(如果是轻微的话)。
讨论我与其他开发人员的困惑,他指出案例1:
var a;
return a === undefined;
两个对象进行比较,而案例2(更快的情况):
var a;
return typeof a === 'undefined';
是一个更加简单和扁平的字符串比较。
我总是认为undefined
在记忆中居住着一个静态的地方,所有三等于做的就是比较那个参考。谁是正确的(如果有的话)?
答案 0 :(得分:3)
根据EcmaScript(参见http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf),如果两个表达式都是字符串(typeof
返回一个字符串),它会进行字符串比较(char by char),否则它只是比较引用(如果是双方是undefined
)。字符串比较无法比简单的两个数字(即内存中的地址)比较更有效。然而,它可能是高度优化的(浏览器不会100%遵循EcmaScript),所以很难说。
适当的基准:
http://jsperf.com/undefined-comparison-reference-vs-string
请注意,在您的测试中,a
的初始值为undefined
(可能或可能无关紧要,似乎确实如此)。
结论:始终使用
return a === undefined;
它绝对不会慢,也可能更快。此外,将某些内容与特殊undefined
对象进行比较而不是字符串似乎更为自然。
答案 1 :(得分:3)
在这种情况下(范围内为var a
),两个已发布的代码片段都具有相同的语义,因为x === undefined
仅在x 未定义且{当x未定义(或在执行上下文中未解析)时,{1}}仅返回“未定义”。
这样,我们最终得到:
typeof x
VS
undefined === undefined
因此,即使在天真实施案例中,根据rules for Strict Equality Comparison,两者之间的“差异”为"undefined" === "undefined"
与SameObject(a,b)
。
但JavaScript的现代实现非常具有竞争力,并且可以看出,针对这种情况进行了非常好的优化。我不知道具体的实现细节,但至少有两种不同的技术可以使两种情况下的性能(在FF / Chrome / Webkit中)相同:
ECMAScript implementations may intern strings,只有一个“未定义”字符串。这将使StringEquals(a,b)
与StringEquals(a,b)
实际上相同,这最终将相当于实现中的“指针比较” - 仅这可以解释为什么性能相同。
此外,由于SameObject(a,b)
是一种常见的习惯用法,因此可以在解析过程中进行翻译,最终会执行相同的特殊调用,比如{{1} }。也就是说,如果选择的话,实施可以完全绕过 typeof x === "undefined"
(和TypeOfUndefined(x)
)。
IE作为“明显的失败者”出现,似乎在这里缺少适用的优化。
===
值的实现超出了ECMAScript的范围;没有强制要求它必须是实现中的单个值/对象。
但实际上,StringEquals
(以及其他特殊的值,如undefined
)很可能被实现为单例(例如“内存中的一个对象”)或作为立即值或值标志(实际上没有未定义的对象)。