I suspect it's because the state of the array while the sort is going on isn't necessarily consistent. You really shouldn't be recomputing the average on each comparison anyway:
array.sort(function(array) {
var avg = array.reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
}, 0);
avg /= array.length;
return function(x, y) {
return Math.abs(x - avg) - Math.abs(y - avg);
};
}(array));
See if that works better. (edit — it gives me the correct answer in Chrome.)
In more detail, my suspicion is that the sort functions where you're seeing weird results may perform swaps on the array in place, and there may be intervals during which one or more original array values is either missing or replicated while the sort mechanism is doing its thing. Thus, your averaging function sees an array (sometimes) with a different list of values, meaning that the average comes out different (sometimes).