I am trying the following code in ideone:
var a = [];
a[0] = 0;
a[5] = 5;
a[6] = undefined;
print("contents before popping:");
for(var e in a) print("\ta[", e, "] =", a[e]);
print("a.length =", a.length);
for (var i = 0; i < a.length; i++)
print("\ta.hasOwnProperty(", i, ") =", a.hasOwnProperty(i));
print("popping -->", a.pop());
print("popping -->", a.pop());
print("contents after popping:");
for(var e in a) print("\ta[", e, "] =", a[e]);
print("a.length =", a.length);
for (var i = 0; i < a.length; i++)
print("\ta.hasOwnProperty(", i, ") =", a.hasOwnProperty(i));
The output goes as follows:
contents before popping:
a[ 0 ] = 0
a[ 5 ] = 5
a[ 6 ] = undefined
a.length = 7
a.hasOwnProperty( 0 ) = true
a.hasOwnProperty( 1 ) = false
a.hasOwnProperty( 2 ) = false
a.hasOwnProperty( 3 ) = false
a.hasOwnProperty( 4 ) = false
a.hasOwnProperty( 5 ) = true
a.hasOwnProperty( 6 ) = true
popping --> undefined
popping --> 5
contents after popping:
a[ 0 ] = 0
a.length = 5
a.hasOwnProperty( 0 ) = true
a.hasOwnProperty( 1 ) = false
a.hasOwnProperty( 2 ) = false
a.hasOwnProperty( 3 ) = false
a.hasOwnProperty( 4 ) = false
In my JavaScript book (well, Crockford's) I read that array's length is calculated as the biggest numerical value of all properties. So, why does it say the length is 5 when the biggest numerical property it has is 0? Thanks!
push() , pop() , shift() and unshift() are only four of many other such methods. These four array methods are quite similar to each other in the way they work and the fact that they are all destructive.
JavaScript Array pop()The pop() method changes the original array. The pop() method returns the removed element.
Use the pop() method to remove the last element of an array. Use the call() or apply() to call the pop() method on an array-like object.
splice alters the length of an array.
A nice thing about Javascript is that its semantics is formally and as unambiguously as possible defined in the standard. Specifically, section 15.4 states that:
The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant.
In other words, everytime you change an array, its length
is adjusted, however, it's only guaranteed to be greater than max(indexes)
, and not necessarily equal to max(indexes)+1
. For example, the pop method always removes the length-1
'th element and decrements length
by one, no matter how many elements an array actually contains.
Also do note that most array methods are generic and don't "know" anything about arrays specifically. They can manipulate arbitrary objects, and if such an object happens to have a property named length
, it will be adjusted according to the above rule. Consider:
foo = {
length: 100,
99: 'hi'
}
alert([].pop.apply(foo)) // hi
alert(foo.length) // 99
alert([].pop.apply(foo)) // undefined
alert(foo.length) // 98
That is, in the context of your question it's irrelevant how exactly arrays are represented - pop
and friends don't use this information.
The "problem" is the assignment of 5
.
The second you do that, the Javascript Array gets filled up with slots which get initialized with the undefined
value.
So calling
a[5] = 5;
causes
[0, undefined, undefined, undefined, undefined, 5]
Then you create also a[6]
and initialize it with undefined
and we get
[0, undefined, undefined, undefined, undefined, 5, undefined]
.length
of 7
.
Now we call a double .pop()
(love the word doublepop) and we get
[0, undefined, undefined, undefined, undefined]
.length
of 5
Actually, as pointed out in the comments, this still seems to be very odd behavior. When initializing any index, the slots before are not really assigned by anything. It creates a sparse array. But then again, if we remove the last two entries, there is only one value left (0
) followed by undefined
values (which somehow became real values, probably because we assigned a 6
manually).
I guess we need an implementation Guru :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With