【问题标题】:Coercion of a number and a string in comparison operators比较运算符中数字和字符串的强制转换
【发布时间】:2017-08-02 01:24:37
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript coercion


    【解决方案1】:

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

    查看"What is the rationale for all comparisons returning false for IEEE754 NaN values?"NaN的行为

    更多详情

    来自 EcmaScript 规范:

    12.9.3 Runtime Semantics: Evaluation 中,指定了&lt;&gt; 运算符的评估,这是重要的一步:

    1. r 为执行抽象关系比较的结果 rval 与 LeftFirst 等于 false

    还有,

    1. 如果 rundefined,则返回false。否则,返回 r

    7.2.11 Abstract Relational Comparison 开头为:

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

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

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

    1. 如果 pxpy 都是字符串,那么
      [...]
    2. 其他
      一种。让 nxToNumber(px)
      [...]
      C。设 nyToNumber(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; }

    【讨论】:

    • 我认为这是不正确的,比较运算符在两边都调用 valueOf(),这意味着比较 'v' 和 5。问题是大于/小于运算符应用严格相等和不同types 表示返回 false。
    • @BenShelton,试试"3" &lt; 5 (true) 、"7" &gt; 5 (true) 以及它的任何变体。关系运算符并不严格。
    • @BenShelton 根据ecma-international.org/ecma-262/6.0/…,两个操作数都被解释为数字
    • @trincot 是的。结果是在将对象与基元进行比较时使用了“valueOf()”,但在这些情况下,字符串会转换为数字。感谢您纠正我。
    • 我添加了一些来自 EcmaScript 规范的引文。
    猜你喜欢
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2019-07-25
    • 2017-03-28
    相关资源
    最近更新 更多