为什么 [null, undefined, []] == "," returns true
Why [null, undefined, []] == ",," returns true
我知道抽象比较会将 LHS 转换为字符串,String([null, undefined, []])
会导致 ',,'
。
但是 String(null)
是 'null'
而 String(undefined)
是 'undefined'
。那么 String([null, undefined, []])
是 ',,'
吗?
那是因为。
- 这就是
==
的定义 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.
- 然后
ToPrimitive
发生:https://tc39.es/ecma262/#sec-toprimitive
- 然后
OrdinaryToPrimitive
发生:https://tc39.es/ecma262/#sec-ordinarytoprimitive 调用 Array.prototype.toString
- 对于它调用的数组
Array.prototype.join(arr)
请参阅 https://tc39.es/ecma262/#sec-array.prototype.tostring
- 这就是
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.
zerkms 的回答是一个很好的答案,如果你想要详细的规格。说白了就是这样:
- String构造函数基本上就是把你传入的参数转换成字符串。
- 在这种情况下,参数是一个数组(通过
[...]
语法创建)。
- 将数组转换为字符串是通过创建一个 comma-separated 列表来表示数组中的值,但有一个有趣的警告:即使
undefined
和 null
会通常被转换为 "undefined"
和 "null"
,zerkms 的回答中引用的 the spec for Array.prototype.join 指定它将使用空字符串而不是进行正常的字符串转换。
- 数组中的第三项是一个空数组(也是通过
[]
语法创建的)。因为没有什么可以用逗号分隔的,所以在转换为字符串时也会生成一个空字符串。
所以你最终得到一个空字符串后跟一个逗号,然后是另一个空字符串,然后是一个逗号,然后是另一个空字符串。因此,",,"
.
另一种看待它的方式是,您基本上是在调用:
[undefined, null, []].join(",")
... 将 undefined
和 null
值视为空字符串。
I know that abstract comparison will convert LHS to String and
String([null, undefined, []]) will result to ',,'.
But String(null) is 'null' and String(undefined) is 'undefined'. So
how String([null, undefined, []]) is ',,'?
为什么您认为 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, []]); // ",,"
尝试将这些示例与您的问题联系起来。
我知道抽象比较会将 LHS 转换为字符串,String([null, undefined, []])
会导致 ',,'
。
但是 String(null)
是 'null'
而 String(undefined)
是 'undefined'
。那么 String([null, undefined, []])
是 ',,'
吗?
那是因为。
- 这就是
==
的定义 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.
- 然后
ToPrimitive
发生:https://tc39.es/ecma262/#sec-toprimitive - 然后
OrdinaryToPrimitive
发生:https://tc39.es/ecma262/#sec-ordinarytoprimitive 调用Array.prototype.toString
- 对于它调用的数组
Array.prototype.join(arr)
请参阅 https://tc39.es/ecma262/#sec-array.prototype.tostring - 这就是
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.
zerkms 的回答是一个很好的答案,如果你想要详细的规格。说白了就是这样:
- String构造函数基本上就是把你传入的参数转换成字符串。
- 在这种情况下,参数是一个数组(通过
[...]
语法创建)。 - 将数组转换为字符串是通过创建一个 comma-separated 列表来表示数组中的值,但有一个有趣的警告:即使
undefined
和null
会通常被转换为"undefined"
和"null"
,zerkms 的回答中引用的 the spec for Array.prototype.join 指定它将使用空字符串而不是进行正常的字符串转换。 - 数组中的第三项是一个空数组(也是通过
[]
语法创建的)。因为没有什么可以用逗号分隔的,所以在转换为字符串时也会生成一个空字符串。
所以你最终得到一个空字符串后跟一个逗号,然后是另一个空字符串,然后是一个逗号,然后是另一个空字符串。因此,",,"
.
另一种看待它的方式是,您基本上是在调用:
[undefined, null, []].join(",")
... 将 undefined
和 null
值视为空字符串。
I know that abstract comparison will convert LHS to String and String([null, undefined, []]) will result to ',,'.
But String(null) is 'null' and String(undefined) is 'undefined'. So how String([null, undefined, []]) is ',,'?
为什么您认为 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, []]); // ",,"
尝试将这些示例与您的问题联系起来。