为什么连接时JavaScript优先转换为字符串,而比较时优先转换为数字?

时间:2018-08-02 20:03:27

标签: javascript types equality coercion

为什么在使用串联+运算符时JavaScript优先将操作数强制转换为字符串,而在执行==相等性检查时优先将操作数强制转换为数字?

'1' + 1被强制为'1' + '1'并返回'11'

'1' == 1被强制为1 === 1并返回true

在比较情况下,它们被强制为数字,而不是字符串。参见以下资源:

1)Douglas Crockford's Encyclopedia

  

==运算符产生的结果与此函数相同:

function coercing_equal(left, right) {
    if (left === right) {
        return true ;
    }
    if (left === null) {
        return right === undefined;
    }
    if (right === null) {
        return left === undefined;
    }
    if (typeof left === 'number' && typeof right === 'string') {
        return left === +right;
    }
    if (typeof left === 'string' && typeof right === 'number') {
        return +left === right;
    }
    if (typeof left === 'boolean') {
        return coercing_equal(+left, right);
    }
    if (typeof right === 'boolean') {
        return coercing_equal(left, +right);
    }
    if
        (typeof left === 'object' &&
        (
            left.constructor === Number ||
            left.constructor === String ||
            left.constructor === Boolean
        ) &&
        (typeof right === 'string' || typeof right === 'number')
    ) {
        return coercing_equal(left.valueOf(), right);
    }
    if (
        (typeof left === 'string' || typeof left === 'number') &&
        typeof right === 'object' &&
        (
            right.constructor === Number ||
            right.constructor === String ||
            right.constructor === Boolean
        )
    ) {
        return coercing_equal(left, right.valueOf());
    }
    return false ;
}

2)MDN

  

当比较中涉及类型转换(即非严格比较)时,JavaScript会按以下方式转换类型String,Number,Boolean或Object操作数:

     

比较数字和字符串时,该字符串将转换为数字值。 JavaScript尝试将字符串数字文字转换为Number类型的值。首先,从字符串数字文字中得出数学值。接下来,将此值舍入为最接近的Number类型值。

     

如果其中一个操作数是布尔值,则布尔值操作数为true时将转换为1,否则为+0。

     

如果将对象与数字或字符串进行比较,JavaScript会尝试返回该对象的默认值。操作员尝试使用对象的valueOf和toString方法将对象转换为原始值(字符串或数字值)。如果此转换对象的尝试失败,则会生成运行时错误。

     

请注意,仅当对象的比较对象为原语时,该对象才会转换为原语。如果两个操作数都是对象,则将它们作为对象进行比较,并且仅当两个对象都引用相同的对象时,相等性检验才为真。

这是否有道理,还是“因为JavaScript”的另一种情况?就我目前的理解而言,很难记住。

1 个答案:

答案 0 :(得分:1)

您为什么会有一个原因? 我相信可能会有不同的方面:

  1. HTML数据未键入-全部为字符串。对于HTTP也是一样。因此,如果您尝试

    ,可能会需要进行大量转换
    element.getAttribute('maxlength')> str.length
    

    所以我们最好只处理字符串/数字混合不是后缀(至少在开始使用EcmaScript时)

  2. 尝试对“ +”和“>”运算符使用相同的方法会生成更多的“ WTF?”。假设我们尝试在各处使用“ toString方法”,那么2> '11'。另一方面,对于“无处不在的toNumber方法”,我们将在字符串连接结果中看到NaN,这是我们想要的更多时候。

是的,看起来令人困惑。但这更多是因为“ +”作为运算符“ add”和运算“ concatenate”的目标不明确。然后,您应该习惯于自动操作它。