13. May 2015 in: English

# Everything is an array index

Javascript engines never cease to amuse me. Let’s look at our good old `Array.prototype.splice`

``````[1,2,3].splice(0,1) //returns 
[1,2,3].splice(1,1) //returns 
[1,2,3].splice(undefined,1) // 1
[1,2,3].splice(false,1) // 1
[1,2,3].splice(true,1) // 2!
``````

Ok, so splice is accepting non-numbers and it’s casting them to booleans and then to numbers, right? Wrong.

``````[1,2,3].splice({},1) // 1
[1,2,3].splice("",1) // 1
[1,2,3].splice("one",1) // 1
``````

Confused? That’s still pretty consistent! Check this out:

``````[1,2,3].splice([],1) //1
[1,2,3].splice(,1) //2
[1,2,3].splice(,1) //3
[1,2,3].splice([1,2],1) //1
``````

Go home javascript, you’re drunk.

### Let’s figure this out anyway.

First:

``````[1,2,3].splice({toString:function(){return 2;}},1) // 3
[1,2,3].splice({toString:function(){return "2one";}},1) // 1
[1,2,3].splice({toString:function(){return "2";}},1) // 3
``````

Ok, that’s something. Looks like it casts stuff to string and expects it to be a number, then if NaN, assumes 0.

``````var a=[];
[1,2,3].splice(a,1)  //returns [ 1 ]
a.toString=function(){return 2;}
[1,2,3].splice(a,1)  //returns [ 3 ]
``````

Confirmed. But what about true ?

Well, it turns out there’s one more step:

``````Number(true) === 1
Number({toString:function(){return 9;}}) === 9
Number({}) //is NaN
``````

So, finally, the closest thing to what `Array.prototype.splice` does to its arguments is:

``````~~Number(arg)
``````
1. Cast to number
2. If input is not a primitive type, `Number()` will call `.toString()`
3. Force-cast to integer (emulated here by `~~`) so all `NaN` results become `0`

Now if that’s not a work of art, I don’t know what is. :)

All return values come from V8 as present in node v0.10.37