JavaScript Arrays: Negative Array Indexes
Welcome to the Negative Array Indexes lesson!
JavaScript arrays don't support negative indexes. If we try to use negative indexes, we'll get very surprising results and subtle bugs.
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
In another lesson, we saw that
.slicecan accept negative arguments.>
['a', 'b', 'c'].slice(-1);Result:
We might expect that to work with regular array indexes, like
someArray[-1]. Unfortunately, it doesn't work. Instead, it returnsundefined, the same value that we get when accessing any index that doesn't exist.>
const arr = ['a', 'b', 'c'];arr[-1];Result:
undefined
What if we try to store a value in a negative array index? Surprisingly, this does work, and we're be able to read the value back!
>
const arr = ['a', 'b', 'c'];arr[-1] = 'd';arr[-1];Result:
'd'
We might assume we're assigning a value at the -1 index. However, what's actually happening is more subtle.
In another lesson, we saw that arrays are a special kind of object, and can have normal object properties.
>
const arr = ['a', 'b', 'c'];arr['name'] = 'Bob';arr['name'];Result:
'Bob'
That's what's happening here. Since negative indexes aren't allowed, our
-1is being converted into the string'-1'and used as an object property.>
const arr = ['a', 'b', 'c'];arr[-1] = 'd';Object.keys(arr);Result:
If we loop over the array with
.forEach, we won't see the "negative indexes" because they're not actually array indexes. This is consistent with other custom properties that we add to arrays.>
const arr1 = ['a', 'b', 'c'];const arr2 = [];arr1[-1] = 4;arr1.forEach(i => arr2.push(i));arr2;Result:
['a', 'b', 'c']
This "negative index" behavior can cause some very subtle bugs! Here's an example.
The function below returns the first array element greater than 2. If no element is greater than 2, it returns
undefined.>
function findGreaterThan2(arr) {const index = arr.findIndex(x => x > 2);return arr[index];}- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
findGreaterThan2([1, 2, 3]);Result:
3
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
findGreaterThan2([0, 1]);Result:
undefined
Our function uses
.findIndex, which returns -1 when it can't find a matching element. When no matching element is found, thearr[index]lookup becomesarr[-1]. That returnsundefinedbecause the array has no'-1'property. OurfindGreaterThan2function then returns thatundefined, as expected.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
findGreaterThan2([1, 2]);Result:
undefined
But what if we call our function on an array with a
'-1'property?Like before, the
.findIndexcall still returns-1, soarr[index]still becomesarr[-1]. And like before, that expression looks up an object property on the array, as if we'd donearr['-1']. If the array actually does have a property named'-1', then the value at that property will be returned!- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
const arr = [1, 2];arr[-1] = 6;findGreaterThan2(arr);Result:
6
Since no element in the array is greater than 2, our function should've returned
undefined. Instead, it returned6, even though the array only contains[1, 2]!Be careful: many programming languages do allow negative indexes, but JavaScript doesn't. It won't throw an exception if you try to read from or write to negative indexes. Instead, you'll get confusing results like those above!