比较运算符中数字和字符串的强制转换

Coercion of a number and a string in comparison operators

我在浏览器控制台(FireFox 和 Chromium)中 运行 以下代码:

console.log('v' > 5);
console.log('v' < 5);

两个陈述 return false。在 'v' < 5 的情况下实际上并不奇怪,但为什么 'v' > 5 return false?据我了解 5 被转换为一个字符串,该字符串按字典顺序与 'v' 进行比较。我错过了什么吗,这里应用了什么强制规则?

威压是反方向的。 'v' 被强制转换为数字,产生 NaN,这将与另一个数字 return false.

进行任何比较

参见 "What is the rationale for all comparisons returning false for IEEE754 NaN values?" NaN

的行为

更多详情

来自 EcmaScript 规范:

12.9.3 Runtime Semantics: Evaluation 中指定了 <> 运算符的计算,其中重要的一步是:

  1. Let r be the result of performing Abstract Relational Comparison rval < lval with LeftFirst equal to false.

并且,

  1. If r is undefined, return false. Otherwise, return r.

7.2.11 Abstract Relational Comparison 开头为:

The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN).

注意:请注意,undefined 将在最终评估中导致 false,如上文第 12.9.3 节第 8 步所述。

然后要求在从操作数中取出原始值后,发现它们不是两个字符串,它们应该被强制转换为Number:

  1. If both px and py are Strings, then
    [...]
  2. Else
    a. Let nx be ToNumber(px).
    [...]
    c. Let ny be ToNumber(py).

求值表达式的例子

这是一系列比较,显示了您可以获得的不同结果:

function test(value, name) {
   if (arguments.length === 1) name = JSON.stringify(value);
   console.log(name + ' < 11.5 === ' + (value < 11.5) +  
       '. Number(' + name + ') = ', Number(value));
}
test('33');
test('3');
test('+11.9');     // coerces to number 11.9 (sign and decimal)
test('0xA');       // coerces to number 10 (hexadecimal notation)
test('');          // coerces to number 0
test('3v');        // invalid number
test('3e2');       // coerces to number 300 (exponent notation)
test('-Infinity'); // coerces to number -Infinity
test(new Date(), 'new Date()'); // coerces to number of milliseconds 
test({ valueOf: x => 2 }, '{ valueOf: x => 2 }'); // coerces to number 2
.as-console-wrapper { max-height: 100% !important; top: 0; }