The short answer is this:
With any in place algorithm that operates on an array, there are no guarantees that intermediate values of the array are valid or complete. The way Chrome has chosen to implement their sort algorithm, there are intermediate steps where the array has values duplicated and is not a complete set of the original array, but this is perfectly acceptable because the sort algorithm is not finished yet.
TLDR version:
If you want to know the exact logic behind this, you can look at the source code for the V8 javascript engine that Chrome uses here https://github.com/v8/v8/blob/master/src/js/array.js
In particular for this case
For short (length <= 22) arrays, insertion sort is used for efficiency.
//This function was copied from the link above
function InsertionSort(a, from, to) {
for (var i = from + 1; i < to; i++) {
var element = a[i];
for (var j = i - 1; j >= from; j--) {
var tmp = a[j];
var order = comparefn(tmp, element); //This is where your comparison function is called
if (order > 0) {
a[j + 1] = tmp;
} else {
break;
}
}
a[j + 1] = element;
}
};
Stepping through this to the first duplicate...
1st comparison: array before comparison [4,3,2,1]
i=1
, j=0
, tmp=a=4
, element=b=3
, order=1
, arr[1]=tmp=a=4
, arr[0]=element=b=3
2nd comparison: array before comparison [3,4,2,1]
i=2
, j=1
, tmp=a=4
, element=b=2
, order=2
, arr[2]=tmp=a=4
3rd comparison: array before comparison [3,4,4,1]
i=2
, j=0
, tmp=a=3
, element=b=2
(this is still in memory from the outer for loop), order=1
, arr[1]=tmp=a=3
, arr[0]=element=b=2
4th comparison: array before comparison [2,3,4,1]...
From this you can see why values are briefly duplicated in the array because of how the for loops are set up in the insertion sort. It is set up to write to the array a minimal amount of times and search values are kept in memory, so intermediate values of the array do not need to be valid.