5

So, I was experimented one day when I came across this question in Stack Overflow and got curious: Maximum size of an Array in Javascript (Maximum size of an Array in JavaScript).

Question is, what is the Maximum depth of an Array in JavaScript?

By depth I mean how much can you nest an array within an array until JavaScript gives up?

[1]           // Depth Level: 1
[1, [2]]      // Depth Level: 2
[1, [2, [3]]] // Depth Level: 3
[1, [...]]    // Depth Level: x?

Is it machine-dependent, is it based on the compiler?

No, I'm not sure if there's any practical use for this but it's still something I'm curious about nonetheless.

Lapys
  • 936
  • 2
  • 11
  • 27

2 Answers2

3

Generally you can nest different arrays until you run out of memory, but you can nest the same array and get an effectively infinite depth array.

var x = [ ];
x.push(x);

x[0][0][0](...)[0]; // Now valid

This shows up as [ [Circular] ] in most debuggers because it's what's called a "circular reference", as in the array contains itself.

This is similar to how you can have self-referential objects:

var x = { };
x.x = x;

// { x: [Circular] }

x.x.x.x.x.x.x.x.x(...).x; // Now valid

JavaScript itself doesn't really care what depth something is, the language has no intrinsic limit. Sometimes circular references are a feature, like x.y refers to something that refers back to x for convenience, a way of showing mutual association. That's technically infinite depth, but it's unlikely you'd use it that way.

Here's a simple example of that phenomenon:

var x = { };
var y = { };

x.y = y;
y.x = x;

x.y.x.y.x.y; // Pointless, but valid.
tadman
  • 208,517
  • 23
  • 234
  • 262
  • 1
    Odd how there's a limit to array length, but not depth. Anyways, thanks. I really appreciate the answer. – Lapys Jun 27 '18 at 21:31
  • @Lapys The array length is represented as an unsigned 32 bit integer, so the length must be able to fit into 4 bytes. With depth, there doesn't really need to be a limit. If `x.x` just points to itself, then it has no problem just fetching the thing at `x`'s address and returning it to you. – pushkin Jul 02 '18 at 05:16
  • @pushkin While that's a good point, is that still the case in 64-bit versions of JavaScript? That sounds like an implementation quirk unless it's defined in the standard, so it's more a practical limit that could change than a theoretical one. – tadman Jul 03 '18 at 16:38
  • @tadman I'm not sure what you mean by 64-bit version of JavaScript. It's true according to the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length). Regarding the max length, yes, it's a practical limit that could change. – pushkin Jul 03 '18 at 16:51
  • @pushkin I mean that in other languages `size_t` varies depending on the ISA, so 64-bit versions have larger max-lengths than their 32-bit counterparts. If JavaScript sticks with 32-bit in both cases that seems odd. – tadman Jul 03 '18 at 16:58
  • 1
    @tadman Ah. It kind of seems like that according to the docs. I guess the benefit is that you don't have to worry about different behavior on different systems - just fix it at 4 bytes. – pushkin Jul 03 '18 at 17:04
1

tadman gave an answer from the runtime perspective (infinite depth), but from a compile-time perspective, there is a limit. It's not one that's built into JavaScript (as far as I know), but consider what the compiler has to do to compile your code.

[1, [2, [3]]]

The compiler needs to turn the above expression into an abstract syntax tree. Roughly:

[ , ]
 /\
1 [ , ]
   /\
  2 [3]

If the compiler runs out of memory when creating those nodes, because there are too many nodes/expressions, then it will crash and your program won't compile. In the case of JavaScript, since it uses a JIT, I guess it's a compilation error that happens at runtime.

pushkin
  • 9,575
  • 15
  • 51
  • 95