0

I inherited some code for a project I'm working on and I frequently see this syntax being used

let arrayAsObject = [];
arrayAsObject.foo = 'bar';
console.log(arrayAsObject.foo); //bar
console.log(Array.isArray(arrayAsObject)); //true

I've never seen an array treated like an object before, I'm wondering functionally what is the difference between the code above and this

let pojo = {};
pojo.foo = 'bar';
console.log(pojo.foo); //'bar'
console.log(Array.isArray(pojo)); //false

With the exception that the pojo is clearly not an array, is there any benefit from doing it one way vs the other. I tend to use objects because that's the way I've always done it and seen it done, this is the first time I've seen arrays used in their place.

richbai90
  • 4,994
  • 4
  • 50
  • 85
  • you could iterate the array with positive integer index and it has a length property and some more prototypes than a standard object. – Nina Scholz Sep 18 '17 at 21:16
  • Arrays are objects that's why you could literally assign property to them but doing it that way might bring up some confusion to those that might want to read it up later except he had a really good reason for using it, which i can't think of. – Ademola Adegbuyi Sep 18 '17 at 21:17
  • 1
    Note that [most things in JavaScript are objects](https://stackoverflow.com/a/9109037/1810460), but only a few things are Arrays. The primary difference between your first bit of code and your second is that `arrayAsObject` supports all the array-specific functionality like `length` and `map`, whereas `pojo` does not. – Hamms Sep 18 '17 at 21:18
  • @AdemolaAdegbuyi I see what you mean, that helps clear up why it works. – richbai90 Sep 18 '17 at 21:19
  • Also note that, as @AdemolaAdegbuyi pointed out, it's generally pretty confusing to assign extra properties like that to an array. If you see a lot of this in the codebase, it's probably a good sign that the previous owner didn't quite know what they were doing – Hamms Sep 18 '17 at 21:19
  • 1
    @Hamms thanks that makes sense, I see that assigning a property to the array actually assigns it to the object, but does not affect the length of the array. Nor can you access the key by numerical index. I think that's to be expected since you're simply adding a property to the object, not a value to the list. – richbai90 Sep 18 '17 at 21:22

1 Answers1

5

Generic arrays in JavaScript aren't really arrays at all (barring optimization), they're objects that inherit from Array.prototype, treat a class of property names ("array indexes"*) specially (well, sort of), and have a special length property. That's it. (JavaScript does, now, also have true arrays in the form of typed arrays, but we're speaking here of the generic [...] array.)

With the exception that the pojo is clearly not an array, is there any benefit from doing it one way vs the other.

Adding non-index properties to arrays is officially just fine (after all, they're objects), but:

  1. May (or may not) cause the JavaScript engine to de-optimize the array. This only matters in the rare situations where the performance of array lookup matters.

  2. May be surprising to people doing maintenance on the code after you.

Although it doubles the number of objects allocated, to avoid those issues but still carry extra information around, you might consider an object with an array as a property:

let obj = {
    foo: "bar",
    data: []
};
console.log(obj.foo); //bar
console.log(Array.isArray(obj.data)); //true

That allows the array to be an array without extraneous information, while still grouping the extra information (foo) with it.

Or you could just be okay with the array having non-index properties. It's up to you.


* "array indexes" - from the specification:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875