【发布时间】:2014-05-19 10:48:03
【问题描述】:
在 JavaScript 中,为什么会这样:
"" < {} 评估为 true 和
"" < [] 评估为 false?
【问题讨论】:
标签: javascript arrays string object compare
在 JavaScript 中,为什么会这样:
"" < {} 评估为 true 和
"" < [] 评估为 false?
【问题讨论】:
标签: javascript arrays string object compare
因为< 强制其参数。它更喜欢比较数字,但如果对象不支持数字原始值,它会处理字符串,最终你会进行词法比较。 String({}) 是 "[object Object]",但 String([]) 是 ""。 "" < "[object Object]" 是 true,但 "" < "" 是 false。
所有血淋淋的细节都是in the spec(公平的警告,说得客气一点,语言很夸张)。
来自您的评论:
如果它首先尝试数字,请考虑
Number({})是NaN并且Number([])是0。比较NaN < 0的结果为false,0 < NaN也是如此。为什么会忽略这些结果?
当我最初说“......它首先尝试数字......”时,我最初说得不好(我已经更新了)。它没有。它只是更喜欢数字。同样,规范中详细的完整细节(上面的各种链接),但基本上:
< 操作对其操作数执行抽象 ToPrimitive 操作。[[DefaultValue]] 方法。[[DefaultValue]] (hint = Number) 调用对象的 valueOf 方法,如果该方法返回原语,则返回它;如果结果不是原始的,[[DefaultValue]] 将返回 toString 的结果。对象(包括数组)的valueOf方法返回原对象不变,所以结果是[[DefaultValue]]返回toString的结果。< 操作看到操作数都是字符串,并在词法上比较它们。如果操作数是原始数字,ToPrimitive 将返回不变的数字,< 将在数学上比较它们;如果它们是 Number 实例(请记住 JavaScript 具有数字、字符串和布尔值的原始版本和对象版本),Number#valueOf 将由 [[DefaultValue]] 调用,并且 Number#valueOf 返回原始数字值。所以< 会在数学上比较它们。
有趣,嗯?
【讨论】:
Number({}) 是NaN 并且Number([]) 是0。比较 NaN < 0 的结果为 false,0 < NaN 也是如此。为什么会忽略这些结果?