Reputation: 946
Arrays are quite something in JavaScript when compared with other programming languages and it's not without its full set of quirks.
Including this one:
// Making a normal array.
var normalArray = [];
normalArray.length = 0;
normalArray.push(1);
normalArray[1] = 2;
normalArray; // returns [1, 2]
normalArray.length // returns 2
So yes, the above is how we all know to make arrays and fill them with elements, right? (ignore the normalArray.length = 0
part for now)
But why is it that when the same sequence is applied on an object that's not purely an array, it looks a bit different and its length
property is off by a bit?
// Making an object that inherits from the array prototype (i.e.: custom array)
var customArray = new (function MyArray() {
this.__proto__ = Object.create(Array.prototype);
return this
});
customArray.length = 0;
customArray.push(1);
customArray[1] = 2;
customArray; // returns [1, 1: 2]
customArray.length // returns 1
Not entirely sure what's going on here but some explanation will be much appreciated.
Upvotes: 0
Views: 506
Reputation: 5151
The array you are trying to create is not a pure array (as you are perhaps aware). Its basically a JavaScript object and is supposed to behave like an object.
While treating an object like an array, its up to you to maintain all it's array like features.
You specifically have to assign a length
property to it and you did it correctly.
Next, the push
method from Array.prototype
is supposed to insert an element to the array and increment the length
property (if any), so it did increment 0 to 1. There you go, the length
now is 1.
Next you used the literal notation of property assignment to Object
, which is similar to something like customArray['someProperty'] = 1
.
While using literal notation, no method from Array.Prototype
is being invoked and hence the customArray object never knows that it has to behave like an Array and its length property remains unaffected. It simply behaves like an object and you get what you got.
Remember the length
is just a property on Array class and this property is appropriately incremented and decremented by every method on Array.
Note: Array like objects are not recommended and its up to you entirely to maintain the index and other Array stuff for such objects.
Upvotes: 1
Reputation: 8930
This may not be the perfect answer, but according to my understanding of Javascript arrays, they are a little bit different than usual objects. (Mainly due to the fact that it maintains a length property, and Objects don't).
So if we take your code for an example:
var normalArray = [];
This is the right way to create an array in Javascript. But what about the below one?
var customArray = new (function MyArray() {
this.__proto__ = Object.create(Array.prototype);
return this
});
Are they same? Let's see..
Array.isArray(normalArray); // true -> [object Array]
Array.isArray(customArray); // false -> [object Object]
So it is clear that although you inherit from the array prototype, it doesn't really create an object with Array
type. It just creates a plain JS object, but with the inherited array functions. That's the reason why it updates the length when you set the value with customArray.push(1);
.
But since your customArray
is only a regular object and for a regular JS object, []
notation is used to set a property, it doesn't update the length (because Objects
don't have a length
property)
Hope it's clear :)
Upvotes: 1
Reputation: 44107
From what I can see, you have a problem with your function:
return this
This should be
return (this);
Just fixes any potential errors you might have. Another thing is you're not using the var
keyword to declare customArray
. These errors might be breaking your code.
Upvotes: 0