JavaScript Function bind()
Aprende la vinculación de funciones en JavaScript: por qué los métodos pierden `this` al pasarse como callbacks o a setTimeout, cómo func.bind() lo soluciona y la aplicación parcial.
En JavaScript, el valor de this dentro de un método se decide cuando se llama a la función, no cuando se escribe. En el momento en que desvincula un método de su objeto — pasándolo como callback o a setTimeout — este olvida a qué objeto pertenecía. La vinculación de funciones es la solución: bloquea permanentemente this a un objeto elegido para que el método se comporte igual sin importar desde dónde se lo llame.
Este capítulo cubre cuándo y por qué se pierde this, cómo func.bind() lo resuelve, cómo usar bind para la aplicación parcial y cómo se compara bind con las funciones flecha.
El problema de "perder this"
Un método funciona bien cuando se llama como object.method(), porque this se establece en lo que esté a la izquierda del punto. Pero pase ese mismo método a otro lugar y el punto desaparece — por lo tanto this se pierde.
La segunda llamada imprime Hello, undefined! porque runLater invocó callback() como una función simple, por lo que this ya no es user. (En modo estricto this es undefined y leer this.firstName lanzaría un TypeError.)
Lo mismo ocurre con setTimeout — almacena la función y más tarde la llama por su cuenta, sin ningún objeto asociado:
Para obtener más información sobre cómo se resuelve this dentro de los métodos, consulte Métodos de objeto, "this".
Solucionarlo con func.bind()
El método func.bind(thisArg) devuelve una nueva función cuyo this se establece permanentemente en thisArg. La función original no cambia — se obtiene una copia vinculada.
Un patrón común es guardar la versión vinculada de vuelta en el objeto para que cada referencia sea segura de pasar:
La vinculación ocurre solo una vez
Una vez que una función está vinculada, this queda fijo para siempre. Llamar a bind nuevamente sobre el resultado no tiene efecto — la segunda vinculación se ignora.
Aplicación parcial: preconfigurar argumentos
bind acepta argumentos después de thisArg, y estos se pasan a la función original antes que cualquier argumento posterior. Esto le permite crear una función especializada a partir de una más general — lo que se llama aplicación parcial.
También puede preconfigurar this y los argumentos al mismo tiempo:
bind vs. funciones flecha
Una función flecha no tiene su propio this — toma this del ámbito circundante en el momento en que se escribe (this léxico). Esto convierte a las flechas en una alternativa ligera a bind cuando necesita mantener el this externo dentro de un callback:
Cuál elegir:
- Use una función flecha para capturar el
thisactual de forma inline, especialmente en callbacks donde no necesita una función reutilizable por separado. - Use
bindcuando necesite una función independiente con unthisfijo para pasarla a otro lugar, o cuando también quiera preconfigurar argumentos. A diferencia de una flecha, una función vinculada puede almacenarse, reutilizarse y pasarse por nombre.
Una advertencia: una función flecha no puede usarse como método de un object que depende de que this apunte al objeto, porque captura this del ámbito que la contiene (a menudo el objeto global) en lugar del llamador.
¿Cuándo usaría esto?
- Al pasar un método a un manejador de eventos,
setTimeout/setInterval,Promise.theno métodos de array comoforEach. - Al construir funciones especializadas a partir de otras generales con aplicación parcial (por ejemplo,
bind(null, presetArg)). - Siempre que un método deba seguir funcionando después de ser desvinculado de su objeto.
Si necesita llamar a una función con un this elegido inmediatamente (en lugar de crear una copia reutilizable), use call/apply en su lugar — vea Decoradores y reenvío, call/apply. Para una mirada más profunda al this de las funciones flecha, vea Funciones flecha revisitadas.