【问题标题】:Why are arrays equal to their corresponding strings?为什么数组等于它们对应的字符串?
【发布时间】:2020-09-24 05:09:58
【问题描述】:

为什么当一个数组与其对应的字符串比较时,它的评估结果为真?

var a = [1,2,3];
var b = '1,2,3';

console.log(a==b);// true

变量a 存储分配给它的数组的内存地址。那么内存地址如何等于该数组的对应字符串。

【问题讨论】:

  • 虽然我不知道== 的确切机制,但重要的是要意识到它不会执行严格的比较。当操作数属于不同类型时,它首先尝试将它们转换为相同类型,然后再进行比较。如果你想进行严格的比较,你会想使用===,在你的情况下它会返回false
  • a 被强制转换为字符串进行比较

标签: javascript arrays reference equality


【解决方案1】:

在“==”的情况下,由于比较松散,数组被转换为toString然后进行比较,所以它等于true。那么会发生什么:

  var a = [1,2,3];
  var b = '1,2,3';

  a == b //is same as
  a.toString() === b //true

如果你想在严格模式下评估为真,你也可以这样做:

var a = [1,2,3];
var b = '1,2,3';

a = a.join(',')

console.log(b === a);

每当您进行松散比较(使用 '==')时,javascript 解释器都会尽力将这两个值转换为通用类型并匹配它们。引用MDN

松散相等比较两个值是否相等,转换后 值到一个共同的类型。转换后(一方或双方可 进行转换),执行最终的相等比较 与 === 完全一样。

现在你的困惑是,

a 里面存储的变量,就是数组的内存地址。因此,在第一个代码 sn-p 中,您说 a==b 与 a.toString==b 相同,但 a 中的内容是内存地址,因此当内存地址转换为字符串时,它如何等于相应的字符串一个数组。

好吧,请注意,当您比较两个变量时,您不是比较它们的内存地址,而是比较它们存储的值 :) 所以转换为 toString 的不是内存地址,而是存储在它。

此外,这种想法还有一个缺陷。

考虑,

        var a = 4, // a holds address of variable a
        b =4; //b holds the address of variable b

现在,这两个变量肯定持有不同的内存地址,因此它们不会等同于true,这是不正确的。我希望你明白了。

【讨论】:

  • 我已经读过,a 里面存储的变量只是数组的内存地址。因此,在第一个代码 sn-p 中,您说 a==b 与 a.toString==b 相同,但 a 中的内容是内存地址,因此当内存地址转换为字符串时,它如何等于相应的字符串数组。请解释我几天以来对这个问题感到困惑。
  • 嗯,当您比较两个变量时,您是在比较存储在寻址而不是实际地址的值。当你写a==b时,你不会比较address of a == address of b
  • 查看更新的答案,如果它消除了困惑,请告诉我
【解决方案2】:

== 比较两个变量而不考虑数据类型,而 === 在严格检查中比较两个变量,这意味着它也会检查数据类型,然后返回 true 或 false。

“==”运算符测试抽象相等,即在进行相等比较之前进行必要的类型转换。

但‘===’运算符测试严格相等,即它不会进行类型转换,因此如果两个值的类型不同,则比较时,它将返回 false。

【讨论】:

    【解决方案3】:

    在 JS 中有两个比较运算符:

    • == 等于

    • === 相等的值和相等的类型

    var a = [1, 2, 3];
    var b = '1, 2, 3';
    
    console.log(a == b);  // Outputs true
    console.log(a === b);  //Outputs false

    【讨论】:

      【解决方案4】:

      这是由于语言的规范和语义。该数组是一个对象,在与字符串比较之前将被强制转换为字符串。

      您可以按照转化路径:
      7.2.15 Abstract Equality Comparison

      1. 如果 Type(x) 是 Object 并且 Type(y) 是 String、Number、BigInt 或 Symbol,返回比较结果? ToPrimitive(x) == y。

      它基本上会经过所有步骤,直到到达 11。
      ToPrimitive(Array) 最终会引用并调用属性 .toString https://tc39.es/ecma262/#sec-array.prototype.tostring
      https://tc39.es/ecma262/#sec-object.prototype.tostring

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-13
        • 2012-02-15
        • 2011-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-11
        相关资源
        最近更新 更多