Binary search that returns bitwise complement of missing index
• First comment is about the way you are adding the functions to the Array prototype : by just adding them this way, you 'pollute' the keys of the array, so anyone doing a for ... in for instance will enumerate also on the added functions.
-->> Use Object.defineProperty to have those function non enumerables.
The pattern could look like : 

(function () {

    var newArrayMethods = {
        //  Returns a shallow copy of this array
        copy: function () {
            return this.slice(0);
        },

        // Returns true if this array contains 'element', returns false otherwise
        contains: function (element) {
            return this.indexOf(element) &gt;= 0 ;
        }            
    }

    // let's install those methods on the prototype
    for (var newMethodName in newArrayMethods) {
        installFunction(newMethodName, newArrayMethods[newMethodName]);
    }

    function installFunction(name, fn) {
        if (Array.prototype[name]) throw ('Array method ' + name + '() already defined.');
        Object.defineProperty(Array.prototype, name, {
            value: fn
        });
    }

})();


• Second thing is that typeof is slow : you don't want to use it within a loop.
The code below also avoids one branch per loop. 

function binarySearch (target, comparator) {
    var l = 0,
        h = this.length - 1,
        m = 0, 
        comparison = 0;
   comparator = comparator || compareNumbers ;

    while (l &lt;= h) {
        m = (l + h) &gt;&gt; 1;
        comparison = comparator(this[m], target);
        if (comparison &lt; 0) {
            l = m + 1;
        } else if (comparison &gt; 0) {
            h = m - 1;
        } else {
            return m;
        }
    }
    return~l;
};

function compareNumbers(a,b) { a-=b;  return (a&lt;0) ? -1 : ( a&gt;0 ) ? 1 : 0 ;  } ;


• Array.splice is to be avoided if you seek performances : it is slow and creates garbage.
Do the insertion yourself.
I wrote below insertion function moving forward, to avoid cache miss.  

You'll notice i changed the insert function signature so it is more alike to the search (target + comparator arguments first). 

Also no need to process an argument that defaults to false.

function binaryInsert(target, comparator, duplicate) {
    var i = this.binarySearch(target, comparator);
    if (i &gt;= 0 ) {
        if (!duplicate) return i;
    } else {
        i = ~i;
    }
    insertOneAt(this, target, i);
    return i;
};

function insertOneAt(arr, item, index) {
    var tmp1=item, tmp2=item;
    var len = arr.length;
    for (; index&lt;=len; index++) {
       tmp2 = arr[index]
       arr[index]=tmp1;
       tmp1=tmp2;
    } 
}


• Detail : change your binaryInsert comment about the return value to something like :  

Returns: Index of new item added to array, or of the existing item if  duplicate==false and the item was found.

• You have also some decision/changes to make about the way you handle duplicates in your search.
As of now search returns any matching item's index (compare==0), it does not ensure, for instance, that it is the smallest index.
If it's ok just mention it, otherwise you have to change a bit your search.    

Since the insert relies on search, your decision on the search will affect insert's semantic as well.