未定义===未定义比较什么

What does undefined === undefined compare?

本文关键字:未定义 什么 比较      更新时间:2024-06-24

在通读了 Lodash 的代码并了解到它经常使用比较类型(在其 _.is* 工具套件中(之后,我运行了一些测试来确认它更快,事实上确实如此(如果稍微如此(。

与一位开发人员同事讨论我的困惑时,他指出,在案例 1 中:

var a;
return a === undefined;

两个对象进行比较,而在情况 2(较快的情况(中:

var a;
return typeof a === 'undefined';

是一个更简单和扁平的字符串比较。

我一直认为undefined在记忆中处于一个静态的位置,所有三等方所做的就是比较那个参考。谁是正确的(如果有的话(?

JSPerf 测试:http://jsperf.com/testing-for-undefined-lodash

在这种情况下(作用域为 var a(,两个发布的代码段具有相同的语义,因为 x === undefined 仅在 x 未定义时为 true,typeof x仅在 x 未定义(或在执行上下文中解析(时才返回"undefined"。

这样,我们最终会得到:

undefined === undefined

与。

"undefined" === "undefined"

因此,即使在幼稚的实现情况下,根据严格相等比较的规则,两者之间的"差异"也是SameObject(a,b)StringEquals(a,b)

但是JavaScript的现代实现非常有竞争力,可以看出,在这种情况下进行了很好的优化。我不知道确切的实现细节,但至少有两种不同的技术可以让两种情况下的性能(在FF/Chrome/Webkit中(相同

  1. ECMAScript 实现可以实习字符串,这样只有一个"未定义"的字符串。这将使StringEquals(a,b)实际上与SameObject(a,b)相同,最终相当于实现中的"指针比较" - 仅此一项就可以解释为什么性能相同。

  2. 此外,由于typeof x === "undefined"是一个常见的习语,因此可以在解析过程中将其翻译为执行相同操作的特殊调用,例如TypeOfUndefined(x)。也就是说,如果它愿意,实现可以完全绕过===(和StringEquals(。

IE是一个"明显的失败者",似乎在这里缺少适用的优化。


undefined的实现超出了 ECMAScript 的范围;没有强制要求它在实现中必须是单个值/对象。

然而,在实践中,undefined(和其他特殊,如null(最有可能实现为单例(例如"内存中的一个对象"(或作为即时值或值标志(这样实际上没有未定义的对象(。

根据 EcmaScript(见 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf(,如果两个表达式都是字符串(typeof返回一个字符串(,它执行字符串比较(逐个字符(,否则它只是比较引用(如果其中一方undefined(。字符串比较不可能比简单的两个数字(即内存中的地址(比较更有效。但是,它可能是高度优化的(浏览器不是100%遵循EcmaScript(,所以很难说。

适当的基准:

http://jsperf.com/undefined-comparison-reference-vs-string

请注意,在您的测试中,a 的初始值是 undefined(可能重要也可能无关紧要,似乎确实如此(。

结论:始终使用

return a === undefined;

它绝对不会更慢,而且可能会更快。此外,将某些东西与特殊的undefined对象进行比较似乎更自然,而不是与字符串进行比较。