【问题标题】:Strange code in jQuery sources: var !== var ? x : y;jQuery 源代码中的奇怪代码: var !== var ? x : 是的;
【发布时间】:2013-01-24 04:33:15
【问题描述】:

最近我在 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 Sizzle

【问题讨论】:

  • 可能是一个错误?那个函数的预期签名是什么?我还看到一个未使用的 _ 参数,...
  • @redShadow 好吧,_ 是可以理解的,因为出于某种原因(可能是为了保持兼容性)作者只需要获取第二个参数,除了我会使用 arguments[1] 来代替。跨度>
  • 我认为正如评论所说,NaN !== NaN总是返回true
  • @VisioN: 使用arguments 会有相当高的性能成本。在像嘶嘶声这样每个毫秒都可以计算的库中,不使用arguments 可能是更明智的选择stackoverflow.com/questions/5325554/…

标签: javascript jquery


【解决方案1】:

其实上面的评论里写的:

// NaN 表示非代码点

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

NaN === NaN 返回false

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

当然是基于性能。这个test 表明a !== aisNaN(a)二十倍

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

更多信息来自Benjamin Gruenbaum

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

来自Jan Dvorak

还要注意{valueOf:function(){return{}}} 确实等于自己

【讨论】:

  • 另外值得注意的是,NaN也不等于其他任何东西,也不是严格意义上的其他任何东西。
  • 另请注意{valueOf:function(){return{}}} 确实等于它自己
  • 但是为什么呢?我的假设是 high !== highisNaN(high)
  • 还要注意isNaN可以被覆盖,使用!==也更便携。
  • a!==aisNaN(a) 不同。例如isNaN("c") 为真,但"c" !== "c" 为假。原因是 isNaN(a) 尝试将其参数转换为 Number 并检查转换结果,但 a!==a 只有在其参数为 NaN 时才成功。
【解决方案2】:

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

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


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

考虑

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

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

【讨论】:

  • NaN === NaN 返回 false 的另一个潜在原因是 NaN 具有多个位模式。
【解决方案3】:

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

一些关于原始问题的 cmets 建议这种检查 NaN 的方法实际上比 isNaN() 快得多

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

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

【讨论】:

  • val - 0不是适合替代parseFloat(val)。比如val = '0xFF',结果就大不一样了。
  • Number(val) 等价于val - 0,或更简单地说是+val
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多