1

On the console, I've attempted to create a circular array, I believe it would cause a stack overflow if attempting to traverse it, but I can't even get a length on it.

var a = [];
a['b'] = a;

a.length;
// 0

a['c'] = c;
a.length; 
// 0

enter image description here

Ryan
  • 14,392
  • 8
  • 62
  • 102

6 Answers6

4

It has a length of 0 because the Array length property returns a number one higher than the highest numeric index.

You'd get a length of 1 if you did this:

var a = [];
a[0] = a;
a.length; // 1

You can assign properties with string keys to an array and it will "work" in that arrays are objects and can have extra properties, but only the numerically (integer) indexed properties participate in array behaviour like .length or .slice(). If you want to use string keys you should be using a plain object:

var a = {};

(Plain) Objects don't have a length (unless you create the property yourself), but you can use Object.keys(a).length to get the number of properties (if you don't care about IE < 9, which doesn't implement .keys() - though there is a polyfill).

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
1

Because you're not adding item to the array, you're creating a property of the object.

Check what's in a.b

Yuriy Galanter
  • 38,833
  • 15
  • 69
  • 136
1
var a = [];
a['b'] = a;

a.length;
// 0

a['c'] = c;
a.length; 
// 0

Array in Javascript only allow numbers as elements key.

You can simply change the key.

var a = [];
a[0] = a;
a.length == 1

Or use a map object instead of an array.

var a = {};
a['b'] = a;
Object.keys(a).length == 1
Tom Chung
  • 1,412
  • 9
  • 12
0

Arrays in JS are considered to be indexed arrays. Ie

var arMyArray = [];

Creates an indexed array, which can be referenced as arMyArray[0], arMyArray[1] etc.

For associative arrays, you will have to use objects

var oMyArray = {};

Creates an object, which can be referenced as oMyArray['name'] = 'aliasm2k' etc.

0

The statement a['b'] = a you wrote actually equals a.b = a which means you create a property, called b, on a, and assign itself to the newly created property b, so you end up a circular reference: a.b.b.b.b.b.b.b.b...b == a. You can check out this, it returns true.

I'm afraid you probably missed that arrays are objects which can have properties as shown above. To make it behavior like array, the elements are added in the way, like a[0] = 1. Because you added object property on the array a you created, rather than adding as an element, so the array a is empty, that's why a.length is 0.

cateyes
  • 5,208
  • 2
  • 24
  • 31
0

From the ECMAScript 5.1 Spec:

Array objects give special treatment to a certain class of property names. 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 2^32 - 1.

In other words, numeric property names are treated as array indices and non-numeric property names are not.

Furthermore,

The value of the length property is numerically greater than the name of every property whose name is an array index.

This means even if I have a single element, the length will depend on the array index of that single element. Specifically, it will always be one greater than the largest array index.

For example:

var list = [];
list[5] = "Hello World";
console.log(list.length); // Outputs 6!

This is also known as a sparse array. Kind of bizarre if you're new to JavaScript.

linstantnoodles
  • 4,350
  • 1
  • 22
  • 24