【问题标题】:Why is "" == [null] true in JavaScript?为什么 JavaScript 中的 "" == [null] 为真?
【发布时间】:2014-10-21 06:57:50
【问题描述】:

我知道 JavaScript 在类型之间的比较中有很多疯狂的结果,尽管我不完全理解为什么。今天遇到了这个。

为什么

"" == [null]

在 JavaScript 中计算为true

感谢@Qantas,提供更多 Javascript 平等娱乐:

【问题讨论】:

标签: javascript


【解决方案1】:

为什么"" == [null] 评估为真?

因为您正在使用non-strict equality operator == 将数组与字符串进行比较,所以它会在比较之前尝试将值转换为相同的类型。

具体发生的事情是:

  1. 您将字符串与对象进行比较,因此对象被转换为字符串:
  2. 当一个数组被转换为一个原始值时,它的.toString()方法被调用(在其他答案中有详细解释),相当于调用.join()
  3. 如果一个元素数组只包含undefinednullreturns the empty string
  4. 最终等价于空字符串

这第三步是出人意料的一步 ([null]+"" != null+""),如果它确实将其转换为字符串,结果将是 "null",而你的相等性为 false。

【讨论】:

    【解决方案2】:

    这是根据 Javascript 的神秘 type-conversion 规则。规则 #8:

    如果 Type(x) 是 String 或 Number 且 Type(y) 是 Object,则返回比较结果 x == ToPrimitive(y)。

    所以比较是在x = ""y = [null] 之间使用ToPrimitive 转换为字符串。转换具有一个空元素的数组会产生一个空字符串(因为 Array.toString() 返回一个以逗号分隔的值列表),因此它们的计算结果为相等。

    【讨论】:

      【解决方案3】:

      "Abstract Equality Comparison Algorithm" 有很多部分,但这里最重要的是:

      如果 Type(x) 是 String 或 Number 并且 Type(y) 是 Object, 返回比较结果 x == ToPrimitive(y)。

      (也有它的镜像。)所以,因为"" 是一个字符串而[null] 是一个对象,我们必须首先通过调用ToPrimitive([null])[null] 转换为一个字符串。这是一个如下描述的内部操作,当它被要求将 Object 实例转换为原始值时:

      返回对象的默认值。通过调用对象的 [[DefaultValue]] 内部方法检索对象的默认值,并传递可选提示 PreferredType。本规范为 8.12.8 中的所有原生 ECMAScript 对象定义了 [[DefaultValue]] 内部方法的行为。

      现在,[[DefaultValue]] 内部操作将对对象调用.toString() 并返回该值。在浏览器控制台中尝试[null].toString()

      > [null].toString()
      ""
      

      你有它。

      编辑: 为什么[null].toString() 是一个空字符串?因为 Array 实例上的.toString() 操作总是只调用.join(),并且总是为nullundefined 值生成一个空字符串。因此,一个包含一个 null 的数组最终只是一个空字符串。

      【讨论】:

      • 我觉得你少了一步;为什么[null].toString() 不返回"null"
      • @Izkata Array.prototype.toString() 返回对数组调用 this.join() 的结果,.join()nullundefined 条目呈现为空字符串。因此,具有一个 null 条目的数组呈现为空字符串。
      • 与将整数转换为字符串或布尔值相同 "" == 0"" == false
      • @sulest 不,不是。在这些情况下,字符串被转换为另一个参数的类型。在 OP 的问题中,另一个参数正在转换为字符串。
      • @Pointy 我的意思是,我认为将评论添加到答案中会很好
      【解决方案4】:

      让我们看一下规范并完成每个步骤

      通过Abstract Equality Comparison Algorithm (§11.9.3)

      1. typeof ""; // stringtypeof [null]; // object 所以不适用
      2. nullundefined 都不适用,因此不适用
      3. 同2
      4. 都不是数字,不适用
      5. 同4
      6. 两者都不是布尔型,不适用
      7. 同样不适用
      8. 最后,一些适用的,现在我们需要知道ToPrimitive([null])

      §9.1 ToPrimitive for Objects 说我们需要计算出[[DefaultValue]] (§8.12.8),其中第 1 点和第 2 点说你是否可以做到 .toString 并且它给出了一个字符串,返回它,所以

      [null].toString(); // ""
      

      所以我们现在正在执行比较"" == "",即true,由抽象相等比较算法的点1。d。

      如果Type(x)String,那么如果xy 是完全相同的字符序列(相同长度和对应位置的相同字符),则返回true。否则,返回false

      【讨论】:

        【解决方案5】:

        JavaScript 是弱类型的;您可以使用以下方法获得错误的结果:

        "" === [null]
        

        【讨论】:

          【解决方案6】:

          值 null 是表示 null 或“空”值的 JavaScript 文字,即不存在对象值。它是 JavaScript 的原始值之一。

          值 null 是一个文字(不是像 undefined 这样的全局对象的属性)。在 API 中,通常在可以预期对象但没有相关对象的地方检索 null。在检查 null 或 undefined 时,请注意相等 (==) 和标识 (===) 运算符之间的差异(使用前者执行类型转换)。

          typeof null        // object (bug in ECMAScript, should be null)
          typeof undefined   // undefined
          null === undefined // false
          null  == undefined // true
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-24
            • 2015-05-09
            • 2018-06-06
            • 1970-01-01
            相关资源
            最近更新 更多