Extendiendo Contextos (this, call, apply y bind)

En este post voy a desmitificar this, en JavaScript esto es algo confuso ya que no trabaja igual a otros lenguajes de programación, también voy a describir como extender contextos de this con los métodos call(), apply() y bind().

this

this simplemente es un variable global tal cual como window (en el navegador), dentro de un ámbito se refiere al objeto actual.

como vemos this es igual a un objeto global como window, esto cambia en modo estricto.

en el modo estricto (use strict) retorna undefined porque this no tiene ninguna valor definido, sin el modo estricto no pasa nada y se ejecuta, this nos ayuda a referenciar objetos globales a una función/objeto o en su misma función/objeto como sitio de llamada, de esta manera:

puede tener el mismo comportamiento si definimos la función fuera del objeto

como vemos el valor de this se mantiene mientras consiga su enlace con un objeto, otro buen uso de this es con los constructores.

cuando creamos el objeto el this se le asigna una propiedad con su valor respectivamente.

call y apply

Los métodos call() y apply() de Function.prototype usan this para enlazar objetos a funciones de una manera muy explícita, call() toma dos parámetros: el primero es el objeto actual que se la va a pasar a la función y el segundo parámetro son argumentos para el objeto, apply() es igual la diferencia es que el primer parámetro se le pasa un vector en vez de un objeto, veamos como trabajan estos métodos en este ejemplo:

call para Super-clase

Podemos aprovechar call() para encadenar constructores para un objeto, de esta manera por ejemplo:

Vectores como Objetos

Un buen truco es usar el método call() pasandole el objeto arguments como objeto actual y junto con Array.prototype.slice, accedemos a estos argumentos como un vector. Veamos este simple ejemplo:

bind

bind() se crea a partir de EcmaScript5, este método crea una nueva función explícitamente cuando es invocada, con el primer parámetro le pasamos el contexto y el segundo los argumentos que se le van a pasar a la función enlazada (el segundo parámetro de bind() es opcional), veamos un ejemplo de un tipico problema cuando perdemos el contexto.

en este caso perdemos el contexto del objeto actual por la función anidada (setInterval())en getPokemon() entonces no puede encontrar el contexto que en este caso es el objeto pokemon, muchos desarrolladores de JavaScript solucionan este problema de esta manera:

mantenemos el objeto actual en el método getPokemon() con la variable self, de esta manera resolvemos el problema del contexto aunque con bind() podemos enlazar el contexto de la función de una manera mucha más explícita.

mucho mejor que enlazar el contexto con una variable, pero que hace bind()? bind() simplemente crea una nueva función cuando es invocada, le pasamos this como primer parámetro para enlazar el contexto del objeto actual en este caso el objeto pokemon y entonces cuando es ejecutada la función (el callback setInterval) se enlaza con el objeto pokemon.

Conclusión

Como describo en este post this es simplemente una variable global y definiendola desde una función u objeto toma su contexto actual, call() y apply() trabajan para definir contextos a funciones explícitamente similar bind() la diferencia es que bind() crea una nueva función para pasarle el contexto actual, espero que con este post puedas evitar estos tópicos problemas de JavaScript.