为什么将0与长度为1的数组进行比较会返回true,而对于数组长度为2或更长的数据,它会返回false? 例如,
var a=[] //undefined
0<a //returns false
a.push(1) // [1]
0<a // returns true
a.push(2) // [1, 2]
0<a // return false
a.push(3) // [1, 2, 3]
0<a // return false
答案 0 :(得分:9)
基本上你会得到一个隐含的类型转换,首先是toString
,
Array
对象会覆盖Object
的toString
方法。对于Array对象,toString方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。当数组要表示为文本值或在字符串连接中引用数组时,JavaScript会自动调用
toString
方法。
与join
一样,然后将其转换为数字。
what you do what you get result array string number ------------ ------------ ------ --------- -------- ---------- var a = []; 0 < a 0 < 0 false [] -> '' -> 0 a.push(1); 0 < a 0 < 1 true [1] -> '1' -> 1 a.push(2); 0 < a 0 < NaN false [1, 2] -> '1,2' -> NaN a.push(3); 0 < a 0 < NaN false [1, 2, 3] -> '1,2,3' -> NaN
答案 1 :(得分:4)
数字和数组之间的比较将触发类型转换。 EcmaScript规范在section 7.1.3中规定了相关规则。根据这些规则,数字不会转换为其他数据类型,但对象(数组是对象)将受到如下转换:
- 让 primValue 为ToPrimitive(参数,提示编号)。
- 返回号码( primValue )。
醇>
section 7.1.1中描述了ToPrimitive
功能:
- 让 exoticToPrim 成为GetMethod(输入,@ @ toPrimitive)。
醇>
@@toPrimitive
是一个符号,您可以Symbol.toPrimitive
访问该符号。问题是Array
没有这个属性,所以这个过程继续这个步骤:
- 返回OrdinaryToPrimitive(输入,提示)。
醇>当使用参数O和提示调用抽象操作OrdinaryToPrimitive时,将执行以下步骤:
- 如果提示为“字符串”,则为 一个。让 methodNames 为«“ toString ”,“ valueOf ”»。
- 否则,
醇>
一个。让 methodNames 为“ valueOf ”,“ toString ”»。
由于提示是“数字”,我们处于第二种情况。接下来的步骤说明了这些方法是按顺序应用的。
现在,Array.prototype.valueOf
只返回数组本身,因此以下子步骤不会返回,因为Type 是 Object(即Array)。
5.c.iii如果Type( result )不是Object,则返回 result 。
结果是后备启动,并且在数组上调用toString
。
因此数组转换为字符串。这是顶部列出的两个步骤中的第一个步骤的结果:
- 让 primValue 为ToPrimitive(参数,提示编号)。
- 返回号码( primValue )。
醇>
第二步更容易:然后将字符串转换为数字,section 7.1.3.1中对此进行了描述。
当Array.prototype.toString
方法创建逗号分隔列表时,只要数组有多个元素,这些字符串就会成为无效数字。如规范中所述,返回值为NaN
。
与<
的任何NaN
比较都会返回false
,这会解释您获得的输出。
答案 2 :(得分:1)
如果您在上面的每一行之后将数组检查为数字,则会为您提供所需的答案。 记住javascript在比较期间做了一些类型转换
Number(a); //insert this after each line
答案 3 :(得分:1)
在像JS这样松散类型的语言中,你必须注意像数组这样的可变类型如何强制转换为不可变类型。基本上[1,2]
变为"1,2"
。
所以[1,2] == "1,2" // <- true
答案 4 :(得分:0)
如果您想比较数组的lenght
,请使用a.length
。
答案 5 :(得分:0)
在JS中,如果数组中只有1个元素,js将像元素一样计算他的值,在你的情况下 - 数字。 例如:
var b[]
b.push(8);
b == 8 //true (but b === 8 is false!)
如果数组中有超过1个元素,则数组类型为数组[数字],这与数字不同,因此您无法将其与数字进行比较。
这就是为什么在你做以下代码之后:
var a=[]
0<a
a.push(1)
0<a
你得到的是,因为a值现在为“1”而且大于0。但是,在下一次推送之后,值为[1,2]并且它不是数字(NaN),这就是为什么你得到假。
答案 6 :(得分:0)
对于比较,javascript尝试通常将操作数转换为数字(首选)。
看看这个例子:
console.log("test" == true);//false
console.log("test" == false);//false
为什么呢?因为“test”试图转换为Number,所以Number(“test”)给出NaN和NaN不等于true或false。 类似地,
0<a becomes 0 < Number(a) becomes 0 < 0 returns "false".
作为一种特殊情况,当数组有一个元素时,Number
能够将其强制转换为数字但是当你添加多个元素时,应该返回什么数字?
在这种情况下,Number(arr)变为NaN,并且0再次不小于NaN。