Reputation: 8150
I noticed something while trying to extend Array.prototype
. I essentially wanted to write a method which allows for the deletion of the last item in an array:
Array.prototype.removeLast = function() {
delete this[this.length - 1];
};
This doesn't produce the result I expected:
>>> var arr = [ 1, 2, 3 ];
[ 1, 2, 3 ]
>>> arr.removeLast();
undefined
>>> arr
[ 1, 2, undefined ]
So I tried another method:
Array.prototype.removeLast = function() {
this.length--;
};
And I got the expected results.
>>> var arr = [ 1, 2, 3 ];
[ 1, 2, 3 ]
>>> arr.removeLast();
undefined
>>> arr
[ 1, 2 ]
1) Why isn't array-index deletion operating like object-key deletion? (With arrays the reference still seems to exist, but just references undefined
. With objects, the reference seems to be deleted entirely.)
2) Is the this.length--
method safe? Could it cause a memory leak, or does
altering an object's length
attribute also cause a check to run and delete any forgotten indices in the array?
3) Do the answers to either of the previous 2 questions vary based on the implementation?
4) What's a good implementation of removeLast
?
Thanks!
Upvotes: 1
Views: 615
Reputation: 42109
As MDN explains for the deleting array elements:
When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.
When the delete operator removes an array element, that element is no longer in the array. In the following example, trees[3] is removed with delete.
For your Array, you are trying to delete an index (with it, its value), which is performed using the the delete
operator, but not in the way you think. The index/value is removed, but how the JavaScript engine assembles the array and manipulates its properties (e.g., length
) will not do what you think. It will still display the missing index w/ undefined
, which is what you see.
To better demonstrate, if do Object.keys( your_array )
you will see that the index that you deleted of your array does not exist; likewise, if you perform Object.values( your_array )
you will see that the undefined
is not returned. For all intents and purposes you deleted the property (the index) and its associated value.
You may consider using use splice
, or pop
(if last index), to remove the last element of the array; however, this isn't without recognizing their own effects:
splice
will reorder the array, shifting the values into new indexes; this is different from delete
, which keeps everything at its original index
pop
will remove only the last item/index from the array
splice
and pop
will both update the length
property of the array
delete
vs splice
vs pop
console.log('\nDELETE');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val)); // notice no undefined
console.log('\nPOP');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.pop();
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val));
console.log('\nSPLICE');
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3,1);
console.log('array: ', trees);
console.log('keys: ', Object.keys(trees) );
console.log('values: ', Object.values(trees) );
console.log('length: ', trees.length );
trees.forEach(val=>console.log(val));
1) Why isn't array-index deletion operating like object-key deletion? (With arrays the reference still seems to exist, but just references undefined. With objects, the reference seems to be deleted entirely.)
It is.
2) Is the this.length-- method safe? Could it cause a memory leak, or does altering an object's length attribute also cause a check to run and delete any forgotten indices in the array?
Best not to operate and manage the length yourself. Historically, different browsers respond differently to length manipulation.
The only time I've seen length
manipulation used in recent years is to clear an array (i.e., arr.length = 0
). This is preferred over assigning it to an new empty array (i.e., arr = []
) for when the array may contain certain properties that should not be lost or re-constructed.
3) Do the answers to either of the previous 2 questions vary based on the implementation?
Yes
4) What's a good implementation of removeLast?
arr.pop()
or arr.splice(-1,1)
Upvotes: 1