【问题标题】:Why does "" < {} evaluate to true?为什么 "" < {} 评估为真?
【发布时间】:2014-05-19 10:48:03
【问题描述】:

在 JavaScript 中,为什么会这样:

"" &lt; {} 评估为 true

"" &lt; [] 评估为 false?

【问题讨论】:

    标签: javascript arrays string object compare


    【解决方案1】:

    因为&lt; 强制其参数。它更喜欢比较数字,但如果对象不支持数字原始值,它会处理字符串,最终你会进行词法比较。 String({})"[object Object]",但 String([])"""" &lt; "[object Object]"true,但 "" &lt; ""false

    所有血淋淋的细节都是in the spec(公平的警告,说得客气一点,语言很夸张)。


    来自您的评论:

    如果它首先尝试数字,请考虑 Number({})NaN 并且 Number([])0。比较 NaN &lt; 0 的结果为 false0 &lt; NaN 也是如此。为什么会忽略这些结果?

    当我最初说“......它首先尝试数字......”时,我最初说得不好(我已经更新了)。它没有。它只是更喜欢数字。同样,规范中详细的完整细节(上面的各种链接),但基本上:

    • &lt; 操作对其操作数执行抽象 ToPrimitive 操作。
    • 对于对象,使用“提示”“数字”调用内部 [[DefaultValue]] 方法。
    • [[DefaultValue]] (hint = Number) 调用对象的 valueOf 方法,如果该方法返回原语,则返回它;如果结果不是原始的,[[DefaultValue]] 将返回 toString 的结果。对象(包括数组)的valueOf方法返回原对象不变,所以结果是[[DefaultValue]]返回toString的结​​果。
    • &lt; 操作看到操作数都是字符串,并在词法上比较它们。

    如果操作数是原始数字,ToPrimitive 将返回不变的数字,&lt; 将在数学上比较它们;如果它们是 Number 实例(请记住 JavaScript 具有数字、字符串和布尔值的原始版本和对象版本),Number#valueOf 将由 [[DefaultValue]] 调用,并且 Number#valueOf 返回原始数字值。所以&lt; 会在数学上比较它们。

    有趣,嗯?

    【讨论】:

    • +1 速度快!问题:如果它首先尝试数字,请考虑Number({})NaN 并且Number([])0。比较 NaN &lt; 0 的结果为 false0 &lt; NaN 也是如此。为什么会忽略这些结果?
    • @Chiru:聪明的问题。我在原版中写得很糟糕,我已经更新了那一点以免误导,并添加了更多细节。
    猜你喜欢
    • 2014-02-16
    • 2018-07-01
    • 2017-04-28
    • 2020-04-03
    • 2023-03-20
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    相关资源
    最近更新 更多