为什么在Javascript中“ 、、” == Array(4)?


119

启动您的解释器/控制台并尝试比较

> ",,," == Array(4)
True

为什么?起初,我想也许是因为您可以将“ ,,”看作是四个字符组成的数组,并带有一个'\ 0'终止符,这也许就是为什么,但是

> "..." == Array(4)

返回“ False”。所以为什么?我知道这是Java语言中鸭子输入的一些特质,但只是好奇是什么突出了这种行为。顺便说一下,Zed Shaw出色的演讲总结了这一点。


14
除C外,很少有语言以程序员可见的方式使用零终止。
乔伊

7
如果我要问,是什么导致了这一发现?
SomeKittens 2012年

1
@SomeKittens Zed Shaw在我链接到问题中的视频中明确提到了这一点(作为对Javascript的批评)。干杯!
ZenLikeThat 2012年

5
@SomeKittens这也是在(非常著名)“笏”谈话中提到,呈现出红宝石和JavaScript的一些怪癖destroyallsoftware.com/talks/wat
Cronco

5
这是始终使用===而不是的许多良好原因之一==
wprl 2012年

Answers:


178

因为右侧操作数将转换为字符串,并且的字符串表示形式Array(4),,,

> Array(4).toString()
  ",,,"

如果使用数组构造函数并传递一个数字,则它将数组的长度设置为该数字。因此,您可以说您有四个空索引(与相同[,,,]),并且数组的默认字符串表示形式是其元素的逗号分隔列表:

> ['a','b','c'].toString()
  "a,b,c"

规范的11.9.3节描述了比较的工作方式。在那里,您会看到(x == y):

8.如果Type(x)是String或Number,而Type(y)是Object,则
返回比较结果x == ToPrimitivey)。

(数组是JavaScript中的对象)

如果您遵循该ToPrimitive方法,最终将发现它调用了该方法toString


2
好吧,现在这对我来说很有意义。谢谢。
ZenLikeThat 2012年

6
这又是因为数组会像使用一样进行字符串化Array.join(",")
duskwuff -inactive- 2012年

您必须流血耐心才能使用javascript编程
matcheek 2012年


31

尝试使用=====在Javascript中使用时,它将尝试强制转换变量,从而导致出现此类问题。控制台正在转换Array(4)为字符串表示形式(即Array(4).toString",,,"。出现逗号的原因是该.toString()函数将它们添加到数组中的单独项目中。

请参见下面的代码段:

document.write( Array(4).toString() );


18

这是因为Array(4)初始化了一个由4个空值组成的数组,并进行了==隐式转换,因此:

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

都是相似的。

==在比较值之前会进行隐式类型转换,这可能导致不可预测的结果。使用===检查的类型和价值。



4

我最初以为它是“原型”……但是经过一番调查,我得出了一个可悲的结论……

显然,这是内部的且晦涩难懂的js事情,没有太多逻辑...

试一试

Array(4)==Array(4)

而且没有强制类型...

Array(4)===Array(4)

你会得到FALSE

你知道null==nullnull===null甚至undefined==undefinedundefined===undefined返回TRUE ...所以...这是一个有点模糊......

Array(4)==[,,,] 也应该是真的


ZEE,Array(4)== [,,,]不会为真。如果将对象与原始对象进行比较,则该对象将被转换为原始对象。这就是它调用toString()的原因。
devsathish 2012年

array(x)应该是构造函数的地址...无论如何,在系统中(不要打扰哪种系统),<identity_X> === <identity_X>始终是真实的!
ZEE 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.