Mistakes I made #01 - Array.prototype.indexOf

— 20.11.2016

Today I want to talk about a misconception about Array.prototype.indexOf I came across a few days ago.

What is it doing?

The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present. (MDN)

So this is pretty simple to understand, right? … Nope! Not for me as my mistake will show you.

Playing around with it

So here are some examples:

[1, 2, 3].indexOf(1);
>> 0

['Cats', 'and', 'Dogs'].indexOf('Dogs');
>> 2

but

['a', 'b', 'c'].indexOf('y');
>> -1

Pretty straight forward, right?

What’s about:

[[1]].indexOf([1]);
>> -1

The misconception

WTF? There is clear evidence that the array [1] is a child of the array [[1]], so it should be found in it, right? Nope! And here comes my misconception:

The phrase “[…] element can be found […]” translates directly to the strict equality comparison indexOf is doing behind the scenes.

So let’s see what this is reporting to us:

[1] === [1]
>> false

Okay… Why is this? Let’s have a look into the ECMAScript spec:

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
1. If Type(x) is different from Type(y), return false.
2. If Type(x) is Number, then […]
3. Return SameValueNonNumber(x, y).

So we are in case 3 here. So what is SameValueNonNumber doing?

In our case of two arrays it “Return[s] true if x and y are the same Object value. Otherwise, return false.” ECMAScript.

So when do two arrays have the same object value?

What happens under the hood?

Whenever we create a new array using the array literal like let myArray = [] we create a new instance like we would do when we would use let myArray = new Array().

So the strict comparison returns true iff two arrays are basically the same instance! So

let myArray = [[1], [2]];

myArray[0] === myArray[0];
>> true

Boooom! ;)

So this is it! So basically my misconception was to believe indexOf would return true whenever the container array contains an array which has the same “value characteristics” as my referenced one. But definitely not! It has to be the same instance!

So be aware of that whenever you use indexOf with non-primitive values! I hope I could help you with that short insight.

Greets,

Andi