49

最近我在 jQuery 源代码中发现了一个奇怪的行(最新版本 1.9.1,Sizzle 包,第 129 行funescape函数):

funescape = function( _, escaped ) {
    var high = "0x" + escaped - 0x10000;
    // NaN means non-codepoint
    return high !== high ?            // <--- LINE 129
        escaped :
        // BMP codepoint
        high < 0 ?
            String.fromCharCode( high + 0x10000 ) :
            // Supplemental Plane codepoint (surrogate pair)
            String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
};

进行比较的原因是什么high !== high?看起来return escaped永远不会被执行。还是我错过了什么?

参考: jQuery 嘶嘶声

4

3 回答 3

59

事实上,它写在上面的评论中:

// NaN 表示非代码点

因此,必须首先执行此比较以处理NaNJavaScript 中的情况:

NaN === NaN返回false

正如James Wiseman所指出的,了解开发人员为什么使用high !== high而不是更清楚的原因也很重要isNaN(high)

它当然是基于性能的。这个测试表明a !== a比快二十倍isNaN(a)

zzzzBov也表示isNaN()可以覆盖,使用!==起来也更便携。

来自本杰明·格伦鲍姆的更多信息:

还值得注意的是,NaN 也不等于其他任何东西,而且在非严格意义上它也不等于其他任何东西

来自Jan Dvorak

还要注意{valueOf:function(){return{}}}不等于本身

于 2013-02-08T12:12:38.987 回答
13

条件high !== high返回 true,当 high 为NaN. 我想知道为什么 jQuery 家伙没有使用 much clearisNaN(high)函数,但这可能是由于 koopajah 指出的性能原因。

NaN( Not- a- Number) 表示不能表示为 的结果Number。这是一个不确定的数字。


为什么 NaN === NaN 返回 false ?

考虑

0/0          = NaN
Math.asin(2) = NaN

你知道那0/0是不同的Math.asin(2),那为什么NaN要等于NaN呢?

于 2013-02-08T12:16:18.660 回答
6

我在这里捎带了一些评论,但认为这是有价值的信息。

对原始问题的一些评论表明,这种检查 NaN 的方法实际上比isNaN()

当与以下替代方案结合使用时,parseInt parseFloat我们有一种非常快速的方法可以转换为数字并检查其数字状态。

减零是某种 JavaScript 性能技巧吗?

所以而不是

function Translated(val) {
    var x = parseFloat(val);
    if (!isNaN(x)) {
        alert("Not a number");
    }
}

我们可以有

function WTF(val) {
    var x = val - 0;
    if (x !== x) {
        alert("Not a number");
    }
}
于 2013-02-08T12:29:58.483 回答