Why is comparing 0 with an array of length 1 returns true whereas it returns false for array length of 2 or more ? For example,
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
Basically you get a implicid type conversion, first toString
,
The
Array
object overrides thetoString
method ofObject
. For Array objects, the toString method joins the array and returns one string containing each array element separated by commas.JavaScript calls the
toString
method automatically when an array is to be represented as a text value or when an array is referred to in a string concatenation.
like join
works and then it is converted to number.
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
The comparison between a number and an array will trigger a type conversion. The EcmaScript specification sets out the rules for this in section 7.1.3. According to these rules, the number is not converted to another data type, but the object (an array is an object) will be subject to a conversion that goes like this:
- Let primValue be ToPrimitive(argument, hint Number).
- Return ToNumber(primValue).
The ToPrimitive
function is described in section 7.1.1:
- Let exoticToPrim be GetMethod(input, @@toPrimitive).
@@toPrimitive
is a Symbol, which you access as Symbol.toPrimitive
. The thing is that Array
does not have this property, and so the process continues with this step:
- Return OrdinaryToPrimitive(input,hint).
When the abstract operation OrdinaryToPrimitive is called with arguments O and hint, the following steps are taken:
- If hint is "string", then
a. Let methodNames be «"toString", "valueOf"».- Else,
a. Let methodNames be «"valueOf", "toString"».
As the hint is "number", we are in the second case. The next steps explain that these methods are applied in order.
Now, Array.prototype.valueOf
just returns the array itself, so the following sub-step will not return, since the Type is Object (namely Array).
5.c.iii If Type(result) is not Object, return result.
As a consequence the fallback kicks in, and toString
is called on the Array.
So the array is converted to string. This is the result of the first of the two steps listed at the top:
- Let primValue be ToPrimitive(argument, hint Number).
- Return ToNumber(primValue).
The second step is easier: the string is then converted to number, which is described in section 7.1.3.1.
As the Array.prototype.toString
method creates a comma-separated list, these strings become certainly invalid numbers as soon as an array has more than one element. As mentioned in the specs, the return value then is NaN
.
Any <
comparison with NaN
returns false
, which explains the output you get.
In a loosely typed language like JS you have to pay attention to how a mutable type like an array coerces into an immutable type. Basically [1,2]
becomes "1,2"
.
So [1,2] == "1,2" // <- true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With