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

最近我在jQuery源代码中find了一个奇怪的行(最新版本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的原因high !== high比较high !== high ? 它显然看起来像return escaped永远不会被执行。 还是我错过了什么?

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

其实这是写在上面的评论:

// NaN表示非代码点

所以必须首先执行这个比较来处理JavaScript中的NaN情况:

NaN === NaN返回false

正如詹姆斯·怀斯曼 ( James Wiseman)所指出的那样,知道为什么开发者使用high !== high而不是isNaN(high)这一点也是很重要的。

这当然是基于性能。 这个testing表明a !== aisNaN(a) a !== a 20倍

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

更多信息来自Benjamin Gruenbaum :

还有一点值得注意的是,NaN并不等于其他任何东西,也不等同于其他任何非严格意义上的东西

从Jan Dvorak :

另请注意{valueOf:function(){return{}}}自身也是相等的

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

NaNN ot – aN umber)表示不能表示为Number 。 这是一个不确定的数字。


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

考虑

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

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

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

对原始问题的一些评论已经表明,这种检查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"); } }