Cuales son las diferencias entre .bind(), .call(), y .apply() ?

Articulo traducido y basado en https://medium.com/@leannezhang/what-are-the-differences-between-bind-call-and-apply-list-some-examples-a56a6f30188e#.2f58ghyif

bind(), call(), y apply() son usados para cambiar la referencia del ‘this’ para una función.

Definicion

func.call(): llama la función dada y permite pasarle un objeto con argumentos
func.apply(): lo mismo que call excepto que los argumentos que pasas deben ser un array de argumentos
func.bind(): regresa una nueva función y permite pasarle un objeto con argumentos en un arreglo cualquier numero de argumentos

Ejemplo

primero, hagamos los objetos licuados y la función mezclar.

var licuadoPlatano= { fruta: 'platano', azucar: '50%', leche: 'normal'};
var licuadoFresa = { fruit: 'fresa', azucar: '20%', leche: 'light'};
function mezclar(nombreCliente) {
console.log('Mezclando ' + this.fruta + ' con leche' + this.leche + ' para ' + nombreCliente);
}

Supongamos que un cliente quiere ordenar un licuado y necesitamos hacerlo.

Usando Call

mezclar.call(licuadoPlatano, 'Lehi'); 
//Mezclando platano con leche normal para Lehi
blend.call(licuadoFresa, 'Karina'); 
//Mezclando fresa con leche light para Karina

Usando Apply

mezclar.apply(licuadoPlatano, [‘Lehi’]);
//Mezclando platano con leche normal para Lehi

mezclar.apply(licuadoFresa, [‘KArina’]);
//Mezclando fresa con leche light para Karina

Using Bind

var mezclandoNuevoLicuado = mezclar.bind(licuadoPlatano, 'Lehi'); 
var mezclandoOtroLicuadiNuevo = mezclar.bind(licuadoFresa, ['Karina']);
mixingAppleBubbleTea(); //Mezclando platano con leche normal para Lehi
mixingLemonTea(); //Mezclando fresa con leche light para Karina

Codigo : https://jsbin.com/wipufo/edit?js,console

Que esta sucediendo?

Puedes ver que todos dan el mismo resultado, .call() y .appy() son casi lo mismo excepto que .call() toma argumentos separados con una coma mientras que .apply() toma un array de argumentos.Ambos son ejecutados inmediatamente.

Call toma argumentos separados con coma y apply toma un arreglo de argumentos

.bind() no se ejecuta inmediatamente, y regresa una nueva función, si quieres ejecutarlo inmediatamente, necesitaras revocar la nueva función, también toma argumentos separados con coma y arreglos de argumentos.