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

时间:2017-03-11 19:40:07

标签: javascript coercion

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

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

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

1 个答案:

答案 0 :(得分:3)

强迫是另一个方向。 'v'被强制为数字,产生NaN,这将与另一个数字进行任何比较,返回false

有关NaN

的行为,请参阅"What is the rationale for all comparisons returning false for IEEE754 NaN values?"

更多详情

来自EcmaScript规范:

12.9.3 Runtime Semantics: Evaluation中,指定了对<>运算符的评估,其中包含以下重要步骤:

  
      
  1. r 成为执行抽象关系比较 rval&lt; lval LeftFirst 等于false
  2.   

  
      
  1. 如果 r undefined,请返回false。否则,请返回 r
  2.   

7.2.11 Abstract Relational Comparison的开头是:

  

比较 x&lt; y ,其中 x y 是值,产生truefalseundefined(表示至少有一个操作数是NaN)。

注意:请注意,undefined将在最终评估中产生false,如上文引用的第12.9.3节第8步所述。

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

  
      
  1. 如果 px py 都是字符串,则为   [...]
  2.   
  3. 否则
      一个。设 nx ToNumber(px)   [...]
      C。让 ny ToNumber(py)
  4.   

评估表达式的示例

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

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