Eligiendo cómo ejecutar una función con call, apply y bind - El Mundo de Angular

Eligiendo cómo ejecutar una función con call, apply y bind

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«!

 

 

 

 

About the Author

Mi nombre es Gustavo Hernán Dohara, soy Ingeniero en Sistemas y, sobre todas las cosas, soy un apasionado por la tecnología; tengo más de 10 años de experiencia en diferentes tecnologías y he decidido compartir mis conocimientos y experiencias con cualquiera que desee aprender: alumnos, empleados, freelancers y vos. Al ritmo que cada uno pueda, en el horario en que cada uno pueda y en el lugar que cada uno elija.