I've been trying to implement a method which takes an array and an index as input, copies the last element of the given array into the entry at the given index, and then truncates the last element (i.e., sets the array shorter by one).
Here is the function which I was given as a suggestion for this task:
function swapWithLastAndRemove(array, index) {
array[index] = array.pop();
}
I then tested this function to make sure that it works on any given index:
for (let index = 0; index < 5; index++) {
var array = [0, 1, 2, 3, 4];
swapWithLastAndRemove(array, index);
console.log(array);
}
And I found it that it works correctly for all but the last index:
[ 4, 1, 2, 3 ]
[ 0, 4, 2, 3 ]
[ 0, 1, 4, 3 ]
[ 0, 1, 2, 4 ]
[ 0, 1, 2, 3, 4 ]
In other words, for the last element, it pops it out of the array, but then rewrites it into the array.
What strikes me, is that this line:
array[index] = array.pop();
Which is equivalent to this line when executed on the last element:
array[array.length - 1] = array.pop();
Could not have possibly resulted with the contents of array
being equal to [ 0, 1, 2, 3, 4 ]
.
The way I see it, there are two options here:
- The statement
array.pop()
is executed before the expressionarray.length - 1
is evaluated - The statement
array.pop()
is executed after the expressionarray.length - 1
is evaluated
In the first case, the contents of array would change as follows:
[ 0, 1, 2, 3, 4 ] // initial state
[ 0, 1, 2, 3 ] // after popping 4
[ 0, 1, 2, 4 ] // after assignment
In the second case, it should have triggered some sort of memory-access violation, because there would be an attempt to write into the 5th entry in the array (array[4]
), when the length of the array is only 4 entries.
I know that NodeJS could be applying some memory-management scheme which would somehow allow this to complete without an "array index out of bound" exception, but I still don't get why it would let this operation "get away with it", and moreover, why the result is what it is.
Is the line array[array.length - 1] = array.pop()
possibly undefined behavior?
Is there even such thing as undefined behavior in JavaScript?