call, apply y bind en JavaScript
Aprende a controlar explícitamente el valor de this usando call, apply y bind, las diferencias entre ellos, y cuándo usar cada método para escribir código más flexible.
TL;DR - Resumen rápido
- call: invoca función con this especificado y argumentos individuales
- apply: invoca función con this especificado y array de argumentos
- bind: crea nueva función con this vinculado permanentemente
- call y apply invocan inmediatamente, bind crea nueva función
- Útiles para préstamo de métodos y control de this
- bind es ideal para event listeners y callbacks
¿Qué son call, apply y bind?
call, apply y bind son métodos de las funciones en JavaScript que permiten controlar explícitamente el valor de this. Estos métodos son fundamentales para manipular el contexto de ejecución de funciones, permitiendo invocar funciones con diferentes objetos como this.
Los tres métodos resuelven el problema de la pérdida de this que ocurre cuando las funciones se invocan sin su contexto original. call y apply invocan la función inmediatamente con el this especificado, mientras que bind crea una nueva función con el this vinculado permanentemente.
Control explícito de this
Estos métodos te dan control explícito sobre el valor de this, lo que es esencial cuando necesitas invocar una función con un contexto diferente al original o cuando quieres evitar la pérdida de this en callbacks.
El método call
El método call invoca una función con un valor dado de this y argumentos proporcionados individualmente. La sintaxis es funcion.call(thisArg, arg1, arg2, ...). call es útil cuando conoces los argumentos que vas a pasar en el momento de la invocación.
El ejemplo muestra cómo call funciona. Invocamos saludar.call(persona, 'Hola'), donde persona se convierte en this dentro de saludar, y 'Hola' es el primer argumento. Esto permite invocar saludar como si fuera un método de persona, aunque no lo sea.
La sintaxis de call es funcion.call(thisArg, arg1, arg2, ...), donde la función se ejecuta inmediatamente con el this especificado. Cada argumento se pasa individualmente, separado por comas. Este método es especialmente útil para el "préstamo de métodos" (method borrowing), permitiendo usar métodos de un objeto en otro que tiene las mismas propiedades. En esencia, call te da control explícito sobre el valor de this.
Préstamo de métodos
call es ideal para el "préstamo de métodos" (method borrowing), donde usas un método de un objeto en otro objeto que tiene las mismas propiedades pero no el método.
El método apply
El método apply es similar a call, pero acepta los argumentos como un array en lugar de individualmente. La sintaxis es funcion.apply(thisArg, [arg1, arg2, ...]). apply es útil cuando tienes los argumentos en un array y quieres pasarlos a una función.
El ejemplo muestra cómo apply funciona. Invocamos Math.max.apply(null, numeros), donde null es el this (irrelevante para Math.max) y numeros es el array de argumentos. Esto permite encontrar el máximo de un array sin desestructurarlo.
La sintaxis de apply es funcion.apply(thisArg, [arg1, arg2, ...]), donde la función se ejecuta inmediatamente con el this especificado. La diferencia clave con call es que los argumentos se pasan como un array en lugar de individualmente. En código moderno, el spread operator ...args es generalmente preferido sobre apply porque ofrece sintaxis más clara. apply es ideal cuando ya tienes los argumentos en un array y necesitas pasarlos a una función.
Spread operator vs apply
En código moderno, el spread operator ...args es preferido sobre apply. funcion(...args) hace lo mismo que funcion.apply(null, args) pero con sintaxis más clara.
Diferencias entre call y apply
call y apply hacen lo mismo (invocar una función con un this específico), pero difieren en cómo aceptan los argumentos. call acepta argumentos individualmente, mientras que apply acepta argumentos como un array.
El ejemplo muestra las diferencias entre call y apply. Ambos invocan la función con el mismo this y argumentos, pero call acepta los argumentos individualmente, mientras que apply los acepta como un array. El resultado es idéntico en ambos casos.
- <strong>Argumentos:</strong> call acepta argumentos individuales, apply acepta array
- <strong>Uso:</strong> call cuando conoces argumentos, apply cuando tienes array
- <strong>Resultado:</strong> Ambos producen el mismo resultado
- <strong>Invocación:</strong> Ambos invocan la función inmediatamente
- <strong>Modernidad:</strong> Spread operator <code>...args</code> reemplaza apply
Prefiere spread operator
En código moderno, prefiere el spread operator ...args sobre apply. funcion(...args) es más claro, más rápido, y no tiene el overhead de crear un array.
El método bind
El método bind crea una nueva función con el this vinculado permanentemente. A diferencia de call y apply, bind no invoca la función inmediatamente, sino que retorna una nueva función que puede ser invocada más tarde. La sintaxis es const nuevaFunc = funcion.bind(thisArg).
El ejemplo muestra cómo bind funciona. Creamos saludarPersona usando bind para vincular persona como this. Ahora podemos invocar saludarPersona sin especificar this, y siempre usará persona como contexto.
La sintaxis de bind es const nuevaFunc = funcion.bind(thisArg, arg1, arg2, ...). A diferencia de call y apply, bind no invoca la función inmediatamente, sino que retorna una nueva función con this vinculado permanentemente. Además, bind puede pre-asignar algunos argumentos, creando funciones parcialmente aplicadas (currying). Es especialmente útil para event listeners y callbacks, donde necesitas mantener this correcto sin invocar la función inmediatamente.
Solución a pérdida de this
bind es la solución clásica a la pérdida de this en event listeners y callbacks. Vincula this permanentemente, asegurando que siempre sea el valor correcto.
Casos de uso prácticos
call, apply y bind tienen numerosos casos de uso prácticos en JavaScript. Desde préstamo de métodos hasta control de this en callbacks, estos métodos son herramientas esenciales para escribir código flexible y predecible.
El ejemplo muestra varios casos de uso prácticos: préstamo de métodos usando call, encontrar el máximo de un array usando apply, y mantener this en event listeners usando bind. Estos patrones son comunes en JavaScript y demuestran la versatilidad de estos métodos.
- <strong>Préstamo de métodos:</strong> Usar métodos de un objeto en otro
- <strong>Arrays como argumentos:</strong> Pasar arrays a funciones que esperan argumentos individuales
- <strong>Event listeners:</strong> Mantener <code>this</code> correcto en eventos
- <strong>Callbacks:</strong> Vincular <code>this</code> en funciones asíncronas
- <strong>Argumentos parciales:</strong> Pre-asignar algunos argumentos con bind
Arrow functions como alternativa
Las arrow functions son una alternativa moderna a bind para mantener this en callbacks. Las arrow functions heredan this léxicamente, eliminando la necesidad de bind en muchos casos.
Resumen
Resumen: call, apply y bind
Conceptos principales:
- •call: invoca con this y argumentos individuales
- •apply: invoca con this y array de argumentos
- •bind: crea nueva función con this vinculado
- •call y apply invocan inmediatamente
- •bind crea nueva función que se invoca más tarde
- •Control explícito del valor de this
Casos de uso:
- •Préstamo de métodos entre objetos
- •Arrays como argumentos a funciones
- •Mantener this en event listeners
- •Vincular this en callbacks asíncronos
- •Argumentos parciales con bind
- •Alternativa: arrow functions para this léxico