4

Why negative indexing of an array in JS doesn't raise an error? It looks like it not intended to have elements with a negative index in an array:

  • array.length doesn't count elements with negative indices.
  • array.forEach() doesn't iterate over elements with negative indices.

UPD. The question is not "why it is thechnically possible" buth rather "why it is allowed by design".

[RESOLVED] Short answer: there is no particular reason, it just happened to become like this.

2
  • 4
    an array is an exotic object. any key would work. Commented Apr 5, 2020 at 16:22
  • Negative indexes don't actually act like real indexes. Commented Apr 5, 2020 at 16:23

3 Answers 3

7

Arrays are the special type of object in JavaScript. It has an extra list of methods and properties (like .length and .forEach), and also it has a list of used indexes (integer positive number starting from zero higher). But just like any other object, it can have additional properties:

var arr = ['A', 'B']; arr.extra = 'C'; console.log(arr[0], arr[1], arr.extra); // A B C 

Because of object properties can be accessed not only via dot but also via square brackets you can access any property using array-like syntax:

var obj = { extra: 'D' }; console.log(obj['extra']); // D console.log(arr['extra']); // C 

Using the same syntax you can assign properties:

obj['x'] = 'E'; obj[33] = 'F'; arr['y'] = 'G'; arr[-1] = 'H'; console.log(obj.x, obj[33], arr.y, arr[-1]); // E F G H 

You can safely use numbers as a property name for the object, it will automatically be converted to a string.

The only difference is when you use positive integer values for the name of the property. Those are interpreted as array indexes.

var arr = []; arr[0] = 'A'; arr[1] = 'B'; arr[-1] = 'C'; arr.forEach(value => console.log(value)) // A, B console.log(arr.length); // 2 console.log( Object.keys(arr) ); // ["0", "1", "-1"] 
Sign up to request clarification or add additional context in comments.

3 Comments

Ok, I see how it works underneath and it makes sense from technical viewpoint. Still it raises confusion and disturbance since JS Reference states that implementation enforces integer as an index (key), presumably, to add more "arrayness" to the object behavior. But, apparently, it doesn't enforce index to be non-negative which is another attribute of "arrayness" and this looks incoherent to me. Unless I'm missing the point.
It is as it is. JavaScript is not the most predictable language. Yet, it works consistently. You just need to know more corner cases to ensure the code is safe.
Oh, I've read the UPD. So, you see, JavaScript wasn't well designed as it was developed almost by one developer and in the short term. That said not every JavaScript feature is planned, but sometimes it is just an if statement in the code "just to make it work". And kept till now, not to brake backward compatibility.
1

Arrays in javascript also can work as hash objects (as almost all objects in js including functions). So doing: a[-1] = -1 simply defines a new key in the array (as object hash) with key value "-1" and value -1.

You should know that almost all objects in javascript can be used as hash objects as well. This is what you see. However these keys (which are not positive integers) for arrays do not count as array keys in the normal sense, only as hash keys.

2 Comments

Reasonable point, though JS Reference states: Arrays cannot use strings as element indexes (as in an associative array) but must use integers. So there is sort of generic array (named associative array) which is actually a hash table. And I expected plain array to have more enforcement on its "arrayness" as it is doing with what could be and index value.
@DixieFlatline, hash keys are automaticaly cobverted to strings when passed as keys in js. So doing a[-1]="foo" in fact is transformed into a["-1"]="foo". And simnce all objects in js can be hash objects this is done . Arrays check their keys if is a positive integer and handle it differently, else default to hash object functionality
0

JS allows negative indices in an array for the simple reason that they are objects under the hood. You can also put [].blah = 5 and it would be valid but a terrible idea.

1 Comment

I think it is not so bad idea, if you need an array + object at the same time. So you can have one instance with both behaviour. jQuery use array-like object for an instance, I think that true array is better if you don't need another prototype chain.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.