Beginner implementation of Merge Sort
Using recursion in sort() is fine: n recursive calls to sort() will let you handle an array of length 2n, so you don't have to worry about too much recursion.  However, it would be better if you wrote the recursion in the standard pattern: base case first, then the recursive case otherwise.  The base case should include empty arrays.

Array.slice(start) gives you a slice from start to the end of the array.

function sort(array) {
    if (array.length &lt;= 1) {
        return array;
    }
    var middle = Math.floor(array.length / 2);
    var left = array.slice(0, middle);
    var right = array.slice(middle);
    return merge(sort(left), sort(right));
}


On the other hand, merge() should not be written recursively.  To obtain a merged array of length n, you'll have to make n recursive calls to merge(), and that could easily result in a stack overflow for a long list.  Furthermore, each slice involves copying nearly the entire array, so the algorithm is grossly inefficient.  You would be much better off writing merge() using a while or for loop.

One of the advantages of mergesort over other sorting algorithms is that it can be a stable sort — that is, if the input contains two elements, neither of which is larger than the other, then they can appear in the same relative order in the output.  For numbers, stability doesn't matter: one 42 is indistinguishable from another 42.  However, it would be good practice to write your merge() function so that it is stable anyway.  For that to happen, if you encounter a tie between left[l] and right[r], you must prefer to take left[l] first, so you should change if (left[0] &gt; right[0]) to if (left[0] &gt;= right[0]), and you must keep your left and right straight instead of swapping them carelessly when merge() calls itself.