3

I'm a bit lost with the following:

When I do a console.log of two different arrays, one is giving me the actual length but not the other.

Output of first array, with good length:

[Object, Object, Object]
  0: Object
  1: Object
  2: Object
  length: 3
  __proto__: Array[0]

Output of the second one, length should be 4 but is actually 0:

[A: Object, B: Object, C: Object, D: Object]
  A: Object
  B: Object
  C: Object
  D: Object
  length: 0
  __proto__: Array[0]

Why do my first array do have a correct length, but not the second one ?

Edit: this is the code generating the above output:

var links = [
  {source: "A", target: "B"},
  {source: "A", target: "C"},
  {source: "A", target: "D"}
];

var nodes = [];

// Compute the distinct nodes from the links.
links.forEach(function(link) {
  link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
  link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

console.log(links);
console.log(nodes);
Pierre
  • 558
  • 1
  • 7
  • 36

2 Answers2

4

The second log message cannot output the length of the array because the values have been assigned to its properties as opposed to its indices, since there are no objects within the actual indices of the array the length property is 0. This occurs because arrays cannot contain non-numeric indices such as A,B,C,D.

So when you execute:

var arr= [];
arr["b"] = "test";

The code is actually assigning the string literal test to the b property of the arr array as opposed to an index. This is possible because arrays are objects in Javascript, so they may also have properties.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Eh, not exactly. `Array` extends `Object` but can still have properties. `A`, `B`, etc are properties on the array. `.push()` will still work, for example. – Evan Davis Jul 25 '14 at 15:17
  • @Mathletics I would consider that a property rather than an indexed object within the array. – Kevin Bowersox Jul 25 '14 at 15:19
  • Right, that's exactly what I said. However, the item being logged is still an array, it just doesn't have any elements. – Evan Davis Jul 25 '14 at 15:19
  • Ahhh gotcha, so if you are logging an array you are through prototypical inheritance logging an object. Technicalities... :) – Kevin Bowersox Jul 25 '14 at 15:21
  • In the sense that all arrays are objects, yes, but you are still logging an actual array. [example](http://jsfiddle.net/uU2Tm/) As I said, arrays CAN have properties and still be arrays. (jQuery collections being a widely-known example) – Evan Davis Jul 25 '14 at 15:22
  • 1
    All arrays are objects, so technically you're right, there's nothing wrong with adding other properties to an object, but arrays are predefined objects, they have a length and a certain way to add and read data, just sticking on random properties is most likely not a very good idea, and not what the OP is trying to do. – adeneo Jul 25 '14 at 15:25
  • @Mathletics Thanks for setting me straight, I have been in the java world lately and a little rusty on the mechanics of JS. – Kevin Bowersox Jul 25 '14 at 15:25
1

The length of an Array object is simply its highest numeric index plus one. The second object has no numeric indices, so its length is 0.

If it were [ A: Object, B: Object, C: Object, 15: Object ], then its length would be 16. The value of length is not tied to the number of actual properties (4 in this case).

Mark Reed
  • 91,912
  • 16
  • 138
  • 175