JS: Introducción a la POO
Teoría: Vinculación (bind)
JavaScript es un lenguaje de programación asíncrono. Debido a esto, las funciones a menudo se llaman como callbacks de otras funciones. Esto es especialmente común en el navegador, donde los callbacks se encadenan unos a otros. Hasta ahora, hemos estado trabajando con funciones simples, lo cual no ha presentado dificultades, pero todo cambia cuando se utilizan métodos.
En esta etapa, aún no hemos trabajado con asincronía, pero eso no debería dificultar la comprensión de la idea. En pocas palabras: la función setTimeout toma una función y un tiempo después del cual debe ser llamada. Cuando llega el momento, se ejecuta. Eso es todo.
Intenta ejecutar este código:
Ahora queremos llamar al mismo código después de un segundo en lugar de inmediatamente. Para ello, utilizamos la función setTimeout(), que llama a la función pasada después de la cantidad de tiempo especificada.
Este código mostrará hello, undefined. ¿Por qué? Porque dentro de setTimeout() pasamos la función print() sin el objeto printer. Esto significa que la función pierde la conexión con el objeto y this ya no se refiere al objeto. Así es como se puede ilustrar lo que sucede:
Cuando no hay contexto, this se convierte en un objeto vacío si estamos hablando de funciones normales.
Este comportamiento a menudo no es deseado. Casi siempre, cuando se pasa un método, se supone que se llamará en el contexto del objeto al que pertenece. Hay varias formas de lograr este comportamiento. El más simple es envolver la función en otra función mientras la llamamos.
Esta es una solución común que también ayuda a capturar variables externas cuando son necesarias para la llamada:
Bind
Otra forma es utilizar el método bind() (que significa "enlazar"). El método bind() está disponible en las funciones y su tarea es enlazar la función con algún contexto. El resultado de llamar a bind() será una nueva función que funciona como la función original, pero con el contexto vinculado a ella.
La función enlazada se fusiona con su contexto de forma permanente. this ya no cambiará.
Además del contexto, bind() acepta argumentos que la función necesita. No todos los argumentos de inmediato, sino cualquier parte de ellos. bind() los insertará en la nueva función (la que se devuelve del método bind()) "parcialmente". Esta técnica se llama "aplicación parcial de funciones". De esta manera, se pueden aplicar los argumentos necesarios de inmediato:
El enfoque con bind() solía ser popular antes de la aparición de las funciones de flecha, pero ahora se usa con poca frecuencia. Las funciones de flecha son más fáciles de entender y se utilizan ampliamente.
Apply & Call
bind() es útil cuando la vinculación del contexto y la llamada a la función ocurren en diferentes lugares y, por lo general, en momentos diferentes. Nos encontraremos con este tipo de código cuando lleguemos a la asincronía en JavaScript.
A veces, la llamada a funciones que utilizan this ocurre inmediatamente junto con la vinculación del contexto. Esto se puede hacer directamente llamando a la función devuelta por bind: ...bind(/* contexto */)():
o se pueden utilizar las funciones especialmente creadas para esto, apply() y call():
Estas funciones hacen dos cosas: cambian el contexto y llaman a la función de inmediato. La diferencia radica en cómo manejan los argumentos de estas funciones: apply() toma los argumentos como una matriz como segundo parámetro, mientras que call() espera argumentos posicionales.
Estas funciones permiten hacer cosas bastante inusuales, como esto:
La llamada anterior es solo una demostración y tiene poco uso práctico. El uso real de call() y apply() se muestra cuando se combina el contexto con funciones de prototipo. Hablaremos de esto en las próximas lecciones.