jQuery源代码中的奇怪代码:var!== var? x:y;

时间:2013-02-08 11:59:01

标签: javascript jquery

最近我在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。或者我会错过什么?

参考: https://github.com/jquery/sizzle/blob/master/sizzle.js#L129

3 个答案:

答案 0 :(得分:58)

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

  

// NaN表示非代码点

因此,必须首先执行此比较以处理NaN案例,如JavaScript:

NaN === NaN返回false

正如James Wiseman指出的那样,了解开发人员使用high !== high而不是isNaN(high)的原因也很重要。

肯定是基于表现。此test表示a !== a isNaN(a) 快20倍。

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

来自Benjamin Gruenbaum的更多信息:

  

值得注意的是,NaN并不等于其他任何东西   好吧,它也不等于非严格意义上的任何其他东西

来自Jan Dvorak

  

另请注意{valueOf:function(){return{}}}确实相同

答案 1 :(得分:13)

当{是高high !== high时,条件NaN返回true。我想知道为什么jQuery人员没有使用更清晰的isNaN(high)函数,但这可能是由于性能原因正如koopajah指出的那样。

NaNN ot - a - N umber)表示无法表示为Number的结果。这是一个未确定的数字。


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

考虑

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

您知道0/0Math.asin(2)不同,那么为什么NaN等于NaN

答案 2 :(得分:6)

我捎带这里的一些评论,但想想这个有价值的信息。

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

parseInt parseFloat的以下替代方法一起使用时,我们可以非常快速地转换为数字并检查其数字状态。

Is Subtracting Zero some sort of JavaScript performance trick?

所以而不是

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");
    }
}