JavaScript's index is 32 bit, so it seems that the array index should be able to go up to 4294967295 for a total of 4294967296 elements. But in fact the highest index is 4294967294. Since an array has a length
property, I don't see a reason for having a null as the last element. Is there a reason the maximum index is 4294967294 but not 4294967295?

- 146,324
- 131
- 460
- 740
-
Closely related: [Maximum size of an Array in Javascript](https://stackoverflow.com/q/6154989/1048572) – Bergi Dec 18 '20 at 22:10
3 Answers
This is because when you create an array using the Array
constructor you may supply it an optional length
as follows:
new Array(length);
The length
of an array is a 32-bit unsigned integer. Hence the length of the array may range from 0
to Math.pow(2, 32) - 1
which is 4294967295
.
For an array of length n
the indices range from 0
to n - 1
. Hence the maximum index of a JavaScript array is (Math.pow(2, 32) - 1) - 1
or Math.pow(2, 32) - 2
, which is 4294967294
.
Thus a JavaScript array may hold a maximum of 4294967295
elements and not 4294967296
elements.
I know. It's pretty illogical, but then again one element won't make a lot of difference.

- 72,912
- 30
- 168
- 299
-
2I'm not sure this is technically correct. While it's true that length is limited to 4294967295 (otherwise it throws a RangeError), I don't think `.length` itself is a 32-bit UInt. In fact, Chrome tells me the type of `.length` for an array object is number, which of course has a MAX_VALUE much greater than 4294967295. – NullUserException Oct 07 '12 at 06:09
-
2@NullUserException Don't confuse the constructor parameter with a property getter. Also, just because the type of the `length` property is `number` doesn't mean it can take every possible value. For example, `typeof Math.sin(x)` is also `number`... – user123444555621 Oct 07 '12 at 06:19
-
@Pumbaa80 I don't follow. The range of `sin(x)` is limited by the nature of the function, how does that even apply here? All I'm saying is that it doesn't look like the limitation on length is not because of its type, but rather an arbitrary limit set by whoever drew up the ECMA. – NullUserException Oct 07 '12 at 06:23
-
1@Pumbaa80 I've done some digging, and JavaScript only has one numeric type: `Number`, which is an IEEE 754 double. This means it's accurate for all integers from -2^53 to 2^53. `ToInt32`, `ToUint32`, etc. are abstract operations, which are not part of the language and only used in the specification. This means there are no unsigned ints (or any kind of int) like this answer suggests, making it incorrect. – NullUserException Oct 07 '12 at 06:46
-
3@NullUserException - JavaScript is an interpreted language. Thus the internal representation of data is under the control of the interpreter. The specification only defines one numeric data type - `Number` which is an IEEE 754 double. Therefore they are internally represented as so. However the specification defines the range of the `length` of an array to be a 32-bit unsigned integer. Hence the interpreter can make an optimization and internally store it as so. When accessed the integer is coerced to a `Number`. This depends upon the implementation of the language and can vary. – Aadit M Shah Oct 07 '12 at 07:09
-
@NullUserException - For example the `length` property in Rhino is [implemented](https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/NativeArray.java#L1368) as a `long` (because Java doesn't support unsigned integers - `int` is signed). It's not stored as a `double` (which in Java is the IEEE 754 double). – Aadit M Shah Oct 07 '12 at 07:21
-
@AaditMShah Got ya. I looked at [Firefox](http://mxr.mozilla.org/mozilla-release/source/js/src/jsarray.cpp) and [Chromium's](http://src.chromium.org/multivm/trunk/webkit/Source/JavaScriptCore/runtime/JSArray.cpp) source and they do indeed use unsigned ints internally. – NullUserException Oct 07 '12 at 07:25
-
@NullUserException: More to the point, array objects are explicitly defined as having a `length` property whose value is [*"...always a nonnegative integer less than 232."*](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4). – T.J. Crowder Aug 09 '13 at 22:30
-
Re my comment above: I guess SO doesn't allow `...` in comments anymore. So obviously that's `2^32`, not 232. – T.J. Crowder Dec 11 '13 at 06:10
The ECMA-262 specification (section 15.4) says:
A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232-1.
The spec also says that the length
property of an array is always less than 232. That would seem to exclude 4294967295 as an array index.

- 232,168
- 48
- 399
- 521
-
Other relevant sections of the spec: 15.4.2.2, 15.4.5.1, 15.4.5.2 – NullUserException Oct 07 '12 at 06:15
-
javascript array can hold 2^32-1=4294967295
.
but array indexes start from 0
thats why ,4294967295-1=4294967294

- 17,226
- 9
- 43
- 70
-
3
-
You mention why indexes are length-1, but not why lengths are 2^32-1 prior to that. That's the missing piece in your answer. – Maple May 22 '14 at 16:11