-1

today I find one strange code

const nums = [1, 2, 3]
console.log(nums[-1])

and I can see the log is undefined. why in JavaScript, we can access the invalid index without throwing any error?

Huan Li
  • 31
  • 5
  • Because that's the way the language is defined to work. – Pointy Oct 14 '19 at 22:32
  • JS Array is a "list-like" Object and object can have different properties. When you use *non-standard* indexes you can no longer rely on `length` property. – PM 77-1 Oct 14 '19 at 22:33
  • "Why?" the language works a certain way is not answerable except by the inventor of the language. You asked for an index and got back undefined, this is not strange in JavaScript. Arrays in JS are associative arrays that can grow to any size, they are not fixed sets of contiguous memory like in other languages. All you need to do is check if the value is defined before trying to use it. – skyline3000 Oct 14 '19 at 22:37
  • @skyline3000 Not any size. The maximum length is 2³² − 1 (so the maximum index is 2³² − 2). You can still assign higher indexes, but they won’t be part of the actual iterable. Also, you don’t need to check the index in most cases. If you’re not using [sparse arrays](https://stackoverflow.com/q/1510778/4642212), you can e.g. iterate over them using available [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Iteration_methods) methods. – Sebastian Simon Oct 14 '19 at 22:45

2 Answers2

1

JavaScript arrays are a class of objects, and array entries are object properties.

Arrays can have other property names, but non-negative integer numbers used to lookup or set array entries affect the array's length property.

The length of an array is maintained as one more than the highest non-negative index value used to store an entry in an array, or a non-negative integer used to set the arrays length property itself.

The reason undefined is returned from looking up a[-1] is that it hasn't been set. If you set it first, you get its value back:

var a = [];
a[-1] = "silly";
console.log(a[-1]);

Negative "indeces" are converted to a string and used as a property name. They don't affect the length property. Because they will confuse anybody trying to maintain the code, avoid using negative indeces deliberately - nobody else does.

traktor
  • 17,588
  • 4
  • 32
  • 53
0

Because that is just a property-access to an undefined property. Negative "indices" will not become part of the array-behavior, but otherwise they have a string-form and thus can be used as property names on objects, which include arrays too.
(Arrays can have any kind of properties, and if a property happens to be index-like enough, that will become included in the array-behaviour)

var someObject={
  "-1":-1,
  "a":"a"
};
console.log(someObject[-1],someObject["a"],someObject[-2]);

var someArray=[1,2,3];
someArray["4"]=5;
someArray.b="b";
console.log(someArray.length,someArray,someArray["b"],someArray.c);

var someVariable;
console.log(someVariable);

undefined is practically a default value for everything.

tevemadar
  • 12,389
  • 3
  • 21
  • 49