最近我在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
答案 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指出的那样。
NaN
(N
ot - a
- N
umber)表示无法表示为Number
的结果。这是一个未确定的数字。
为什么NaN === NaN返回false?
考虑
0/0 = NaN
Math.asin(2) = NaN
您知道0/0
与Math.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");
}
}