【问题标题】:Why [null, undefined, []] == ",," returns true为什么 [null, undefined, []] == ",," 返回 true
【发布时间】:2020-08-06 04:40:05
【问题描述】:

我知道抽象比较会将 LHS 转换为字符串,String([null, undefined, []]) 将导致',,'

但是String(null)'null'String(undefined)'undefined'。那么String([null, undefined, []]) 是怎样的',,'

【问题讨论】:

  • 我喜欢这个问题,但你能格式化一下吗?很难阅读。
  • 另外,标题和帖子正文似乎在问不同的问题。非空字符串是真实的,数组对象是真实的,并且数组的字符串化方式与 undefinednull 不同,所以我不觉得这种行为令人惊讶。

标签: javascript arrays comparison-operators coercion


【解决方案1】:

那是因为。

  1. == 就是这样定义的 https://tc39.es/ecma262/#sec-abstract-equality-comparison 参见第 11 步:If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return the result of the comparison ? ToPrimitive(x) == y.
  2. 然后ToPrimitive 发生:https://tc39.es/ecma262/#sec-toprimitive
  3. 然后OrdinaryToPrimitive 发生:https://tc39.es/ecma262/#sec-ordinarytoprimitive 调用Array.prototype.toString
  4. 对于它调用的数组Array.prototype.join(arr)https://tc39.es/ecma262/#sec-array.prototype.tostring
  5. Array.prototype.join就是这样实现的:https://tc39.es/ecma262/#sec-array.prototype.join,最重要的步骤:
Repeat, while k < len,

* If k > 0, set R to the string-concatenation of R and sep.
* Let element be ? Get(O, ! ToString(k)).
* If element is undefined or null, let next be the empty String; otherwise, let next be ? ToString(element).
* Set R to the string-concatenation of R and next.
* Set k to k + 1.

【讨论】:

    【解决方案2】:

    如果您想要详细的规格,zerkms 的答案是一个很好的答案。用更简单的语言来说是这样的:

    1. String 构造函数基本上将你传入的参数转换为字符串。
    2. 在这种情况下,参数是一个数组(通过[...] 语法创建)。
    3. 将 Array 转换为字符串是通过创建一个以逗号分隔的字符串表示形式的其中值列表来完成的,但有一个有趣的警告:即使 undefinednull 通常会转换为 "undefined" 和zerkms 的答案中引用的"null"the spec for Array.prototype.join 指定它将使用空字符串而不是进行正常的字符串转换。
    4. 数组中的第三项是一个空数组(同样通过[] 语法创建)。因为没有什么可以用逗号分隔的,所以转换成字符串时也会产生一个空字符串。

    所以你最终会得到一个空字符串,后跟一个逗号,然后是另一个空字符串,然后是一个逗号,然后是另一个空字符串。因此,",,"

    另一种看待它的方式是,您基本上是在调用:

    [undefined, null, []].join(",")
    

    ... 将 undefinednull 值视为空字符串。

    【讨论】:

    • 对,这是规范的重新措辞,我很抱歉,删除了我的其他评论
    • @zerkms:啊,确实,你是对的。我会解决的...
    • 我的意思是 - 很难同时用“可以理解”和“不太错误”来表达它:-)
    • 我完全明白你的意思。希望我的重新措辞不那么错误,而且基本上还是可以理解的。
    • 是的,现在好多了,再次为吹毛求疵感到抱歉
    【解决方案3】:

    我知道抽象比较会将 LHS 转换为 String 和 String([null, undefined, []]) 将导致',,'。

    但是 String(null) 是 'null' 而 String(undefined) 是 'undefined'。所以 String([null, undefined, []]) 是 ',,' 是怎么回事?

    您为什么认为func([x, y, z]) 应该等于func(x) + func(y) + func(z)

    查看这些示例:

    String([1, 2]); // "1,2"
    String([null]); // ""
    String([undefined]); // ""
    String([[]]); // ""
    String([1, null, undefined]); // "1,,"
    
    // In same way 
    
    String([null, undefined, []]); // ",,"
    

    尝试将这些示例与您的问题联系起来。

    【讨论】:

      猜你喜欢
      • 2014-05-11
      • 2015-02-22
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      相关资源
      最近更新 更多