5

I use Chrome browser 60.x, and test the code isNaN([3]). The result is false, but I cannot understand it.

[3] is an Array, and it is not empty. I think [3] is array object, and it is not an number.

Otherwise the result of isNaN(["ABC"]) is true. And another result of isNaN([1,2,3]) is true. So I guess javascript engine is force changing array to number which the array has a single element.

Please let me know what is happened isNaN function for array parameter.

ref1: Why is isNaN(null) == false in JS?
ref2: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN


[EDIT] Thank you everyone for answering.

I understand javascript parsed the value implicitly before comparison.

And I found a useful link while reading Nina Scholz's answer.
The comparison table : http://dorey.github.io/JavaScript-Equality-Table/

IvoryCirrus
  • 622
  • 1
  • 4
  • 15
  • 2
    In title you say that `isNaN([3]) = false`, in question you say that it is true... What is it? – campovski Sep 04 '17 at 06:53
  • Strong typing versus weak typing. In. Some languages, implicit conversions are allowed for convenience. In others, all must be explicit for reliability. – WGroleau Sep 04 '17 at 07:33
  • While `[3]` is deterministic `[1,2,3]` is not and JS implicitly makes use of this fact by applying type coercion. – Redu Sep 04 '17 at 08:33

5 Answers5

6

When you use isNaN it tries to parse your input value into the number and then checks if it is NaN or not.

See some examples.

For an array with one item, the Number() function returns an object, which actually hold the first item as a value (see console.log). For many items it returns NaN, so you get isNaN's result -> true.

const a = new Number([3]);
console.log(`a is ${a}`);
console.log(`isNaN(a) - ${isNaN(a)}`);


const b = new Number([3,4,5]);
console.log(`b is ${b}`);
console.log(`isNaN(b) - ${isNaN(b)}`);
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
3

According to the rules for equality comparisons and sameness, the array is converted, first with toString and then to a number for checking.

console.log(isNaN([3]));
console.log(isNaN('3')); // convert with toString to a primitive
console.log(isNaN(3));   // convert to number
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This rather goes under the [standard for `isNaN`](https://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number) ..? (Appeared to be pretty complex.) – Teemu Sep 04 '17 at 08:49
2

Javascript works in the following way: It tries to convert the object to integer if the argument of the function is expected to be an integer. For example running

x = increment([3])

will result in x = 4. Therefore running

isNan([3])

will result in false, since [3] gets converted to 3 and 3 is a number. Similarly, ["ABC"] cannot get converted to integer, therefore isNaN(["ABC"]) = true. Also, javascript fails to convert [1,2,3] to a number, since there are three numbers in array, therefore

isNaN([1,2,3]) = true
campovski
  • 2,979
  • 19
  • 38
1

Because, as a shorthand in Javascript,, arrays containing only one number are considered castable to the number it contains. You can see this behavior with ==

3 == [3] // returns true

Additionaly, that's also why [0] is a falsy value, whereas [n] with n not zero is a truthy value, an horrible potential source of bugs.

[0] == false // returns true 
[1] == false // returns false
Pac0
  • 21,465
  • 8
  • 65
  • 74
  • you can use triple equals to include type-checking as well. 3 === [3] // false – Lostfields Sep 04 '17 at 06:59
  • exactly, my point was about a implicit cast that occurs, and these casts occurs when you use double-equals only. that's why I don't think it is relevant to include it in answer. – Pac0 Sep 04 '17 at 06:59
0

So as we know isNaN([3]) // returns false

A workaround to test number vs array with number

Number([3]) === [3] //returns false 
Number(3) === 3 // returns true 

Remember that === means matching the values and type

Duba911
  • 11
  • 1