6

In the below visualisation,

enter image description here

There are two array objects(cars & bikes) that are created with below syntax,

var cars = new Array("Saab", "Volvo", "BMW");
var bikes = ["Honda", "Yamaha"];

whose [[Class]] property value is Array.

In addition, we also have Array.prototype, which is fully functional array, as shown below,

> Object.prototype.toString.call(Array.prototype);
      "[object Array]"
> Array.prototype[0] = "Volvo";
      "Volvo"
> Array.prototype[1] = "BMW";
      "BMW"
> Array.prototype.length;
      2

Generally, When you put something on the prototype, every instance of the object shares the same properties.

Question:

With length property as member, What is the idea behind Array.prototype being fully functional array?

Kilian Foth
  • 107,706
  • 45
  • 295
  • 310
overexchange
  • 2,245
  • 2
  • 17
  • 47
  • 2
    My understanding is that .prototype is always an object, because the whole point of a prototype is that it's a map from method names to actual methods shared by several different objects. The fact that Array.prototype is also an array is related to the fact that all arrays are special objects. Are you asking why Array.prototype is an array and not a regular object? Or why JS prototypes are not restricted to being string -> function maps? Or why JS arrays are special objects? Or something else? – Ixrec Dec 06 '15 at 14:12
  • 1
    You're probably asking the wrong question. The right question is "why isn't `array` *not fully functional?*" And I think the answer to that is self-evident: for the same reasons that you split the functionality of a class into an abstract class and a class that inherits from it. – Robert Harvey Dec 06 '15 at 16:00
  • @Ixrec Why `Array.prototype` is more than `Object`? More in the sense of providing facility to store elements. – overexchange Dec 06 '15 at 17:29
  • @overexchange But objects also store elements. If you mean storing elements with integer keys, arrays don't do that either, because arrays are objects. The integer keys always get converted to strings (because Javascript is a bit weird). `[42]` is essentially the same thing as `{ "0": 42 }` but with a different prototype and that funky `length` property. – Ixrec Dec 06 '15 at 17:35
  • @Ixrec But not all objects have `length` property that get incremented for each property stored in the object. This is where I say that `Array.prototype` is fully functional array. – overexchange Dec 07 '15 at 00:18

1 Answers1

2

The Array-prototype is itself a fully functional array, because it need to contain all the functionality which is necessary for an object to function as an array. The Array-instances inherit all their functionality through the prototype.

According to the spec:

The Array prototype object is itself an array; its [[Class]] is "Array", and it has a length property (whose initial value is +0) and the special [[DefineOwnProperty]] internal method described in 15.4.5.1.

JacquesB
  • 57,310
  • 21
  • 127
  • 176
  • But `length` property is instance level property. Every array instance has its own `length` value. Why would you place the `length` property in `Array.prototype`? It would make sense to place `length` property in `Array` constructor function, upon instantiation, every instance will have its own `length` property that signifies array length. But `length` property of `Array` constructor function signifies the number of arguments expected by constructor function – overexchange Dec 10 '15 at 12:42
  • @overexchange: Objects does not inherit properties from the constructor, only from the prototype. Therefore the Array.length has no relation the the Array.prototype.length. – JacquesB Dec 10 '15 at 14:21
  • @JacquesB This means that `length` is a shared property between all array instances and as soon as an instance modifies its own `length` property, that shared `length` becomes shadowed, and therefore useless (because any arithmetic operation results in a shadowing occuring, e.g `x.length++` is actually `x.length = x.length + 1`). So, is the only use of that property, according to you, so that all array instances get an initial `length` property ? – doubleOrt Oct 26 '17 at 19:36
  • Every array object has a `length` property that is in no way derived from `Array.prototype.length`. Just try setting `Array.prototype[10] = 42`, which makes `Array.prototype.length` equal to 11, but of course newly created arrays do not pick this up. They do inherit the element--try `[][10]`. Hardly a desirable behavior. Whatever may be the reason for Array.prototype to be an array, `length` has nothing to do with it. – cayhorstmann Aug 13 '19 at 15:54
  • Why can't it be a ordinary object with all the properties such as push etc implemented, so that Array Instance inherit from it ? – Suraj Jain Jan 25 '20 at 05:19