Eligiendo cómo ejecutar una función con call, apply y bind
· javascript
Las funciones -recuerden que en Javascript son objetos-, tienen 3 métodos de los que podemos disponer: call, apply y bind. ¿Para qué? El lenguaje nos proporciona estos métodos para que podamos setear la palabra clave «this« ya que, si no lo hiciéramos, el propio motor de Javascript setearía el valor de «this» a su antojo en cada Execution Context.
¿Y cuál es el problema de que el Execution Context nos setee la palabra reservada «this»?
Como problema ninguno, pero muchas veces queremos o esperamos que «this» tenga un valor en particular y no podemos dejar que el motor de Javascript decida por nosotros. Por ejemplo, suponéte que tenemos el objeto:
var persona = {
nombre:'Gustavo',
apellido:'Dohara',
getNombreCompleto:function() {
var nombreCompleto = this.nombre + ' ' + this.apellido;
return nombreCompleto;
}
}
var logName = function() {
console.log('Log: '+this.getNombreCompleto());
}
logName();
¡Este código no funciona! ya que en la función «logName» se está intentando acceder al método «getNombreCompleto», pero este método no existe en el Execution Context Global (sólo existe en el objeto persona).

Pero estaría bueno que podamos decirle a Javascript que queremos que «this» valga ese objeto persona, ¿no?. Sí, sería genial, ¡y por suerte podemos!
De hecho, existen 3 métodos que nos permiten definir nuestro «this» a nuestro antojo y son los siguientes:
bind()
Con bind podemos crear una nueva función asignándole un nuevo «this«, de la siguiente forma:
var logPersonaName = logName.bind(persona);
logPersonaName();
Como podemos ver, tomamos la función «logName» y llamamos a la función «bind» pasándole como argumento nuestro nuevo «this«. Notemos que no usamos la misma función, sino que bind nos devuelve una nueva función con un nuevo «this» seteado en su contexto, y es esta nueva función la que ejecutamos.
Este sería el código completo:
var persona = {
nombre:'Gustavo',
apellido:'Dohara',
getNombreCompleto:function() {
var nombreCompleto = this.nombre + ' ' + this.apellido;
return nombreCompleto;
}
}
var logName = function() {
console.log('Log: '+this.getNombreCompleto());
}
logName();
var logPersonaName = logName.bind(persona);
logPersonaName();
call()
Si, por otro lado, queremos ejecutar nuestra función con un nuevo «this» sin tener que crear ningún nuevo objeto, podemos pasarle los parámetros que necesite la función:
logName.call(persona, 'argumento1', 'argumento2');
Nuestro código completo sería el siguiente:
var persona = {
nombre:'Gustavo',
apellido:'Dohara',
getNombreCompleto:function() {
varnombreCompleto=this.nombre+' '+this.apellido;
returnnombreCompleto;
}
}
var logName = function(arg1, arg2) {
console.log('Log: '+this.getNombreCompleto());
console.log('Argumentos: ', arg1, arg2 );
}
logName.call(persona, 'argumento1', 'argumento2');

apply()
Por último, tenemos apply que hace exactamente lo mismo que call, pero con la diferencia de que los argumentos que vayamos a pasarle, los haremos mediante un array:
logName.apply(persona, ['argumento1', 'argumento2']);
El código completo quedaría de la siguiente forma:

Esta forma de pasar argumentos como si fuera un array es muy útil si queremos pasar argumentos de forma dinámica.
Conclusiones
El correcto uso de «this» puede ser la diferencia para que nuestro codigo haga o no lo que queramos. Tener seteado nuestro «this«, dependiendo del Contexto de Ejecución en el que estemos, es clave para el correcto funcionamiento de nuestros programas. Con apply, call y bind en tu set de herramientas ¡no vas a tener mas problemas con «this«!