Javascript es un lenguaje de programación versátil y potente que permite a los desarrolladores utilizar diferentes técnicas para manipular el valor de this en funciones. Entre estas técnicas se encuentran tres métodos importantes: call(), apply() y bind(). Estos métodos permiten cambiar el contexto de ejecución de una función y son fundamentales para comprender cómo funciona this en diferentes situaciones. En este capítulo, exploraremos en profundidad call(), apply() y bind(), su sintaxis, sus diferencias y cómo se pueden utilizar en diferentes escenarios.
¿Qué es «this» en JavaScript?
Antes de adentrarnos en los métodos call(), apply() y bind(), y aunque lo vimos en el capítulo anterior, volvemos a recordar que es importante comprender el concepto de this en Javascript. En términos sencillos, this se refiere al objeto al que pertenece la función que se está ejecutando. El valor de this depende del contexto de ejecución y puede variar según cómo se invoque una función.
El valor de this puede ser:
- Global Object (en el navegador, es el objeto window): Cuando una función se invoca en el contexto global, this hace referencia al objeto global, que es el objeto window en el navegador o «b en Node.js.
- Objeto de llamada (objeto que llama a la función): Cuando una función es parte de un objeto y se llama a través de ese objeto, this hace referencia a ese objeto.
- Nuevo objeto (usado en constructoras): Cuando una función se utiliza como constructora para crear un nuevo objeto, this se refiere al nuevo objeto creado.
- Objeto específico (usado en funciones de tipo flecha): Las funciones de tipo flecha no tienen su propio valor de this; en su lugar, this se toma del ámbito que rodea la función.
El Método call()
El método call() es una función incorporada en Javascript que se utiliza para llamar a una función con un valor de this específico y argumentos pasados individualmente. La sintaxis de call() es la siguiente:
func.call(thisArg, arg1, arg2, ...);
func
: La función que se va a llamar.thisArg
: El valor que se establecerá como this dentro de la función «func».arg1
,arg2
, …: Los argumentos que se pasarán a la función «func».
El uso más común de call() es cambiar el valor de this en una función para que haga referencia a un objeto específico. Veamos un ejemplo:
const persona = {
nombre: "John",
saludar: function() {
console.log(`Hola, soy ${this.nombre}`);
}
};
const otraPersona = {
nombre: "Jane"
};
persona.saludar(); // Output: Hola, soy John
// Usando call() para cambiar el valor de "this" dentro de la función
persona.saludar.call(otraPersona); // Output: Hola, soy Jane
En el ejemplo anterior, la función saludar()
dentro del objeto persona
hace referencia al objeto persona
como su valor de this. Sin embargo, al usar call() en la última línea, cambiamos el valor de this dentro de la función para que haga referencia al objeto otraPersona
en lugar de persona
.
El Método apply()
El método apply() es similar a call(), pero en lugar de pasar los argumentos individualmente, se pasan como un arreglo. La sintaxis de apply() es la siguiente:
func.apply(thisArg, [arg1, arg2, ...]);
func
: La función que se va a llamar.thisArg
: El valor que se establecerá como «this» dentro de la función «func».[arg1, arg2, ...]
: Un arreglo que contiene los argumentos que se pasarán a la función «func».
Veamos un ejemplo similar al anterior pero usando apply() en lugar de call():
const persona = {
nombre: "John",
saludar: function(genero, edad) {
console.log(`Hola, soy ${this.nombre}, soy ${genero} y tengo ${edad} años`);
}
};
const otraPersona = {
nombre: "Jane"
};
persona.saludar("hombre", 30); // Output: Hola, soy John, soy hombre y tengo 30 años
// Usando apply() para cambiar el valor de "this" y pasar argumentos en un arreglo
persona.saludar.apply(otraPersona, ["mujer", 25]); // Output: Hola, soy Jane, soy mujer y tengo 25 años
En el ejemplo anterior, hemos usado apply() para cambiar el valor de this en la función saludar()
y también para pasar los argumentos en un arreglo.
El Método bind()
A diferencia de call() y apply(), que llaman a una función inmediatamente con un valor de this específico, el método bind() crea una nueva función con un valor de this vinculado pero no la llama de inmediato. La sintaxis de bind() es la siguiente:
const nuevaFunc = func.bind(thisArg, arg1, arg2, ...);
func
: La función a la que se va a vincular el valor de «this».thisArg
: El valor que se establecerá como «this» dentro de la función vinculada.arg1
,arg2
, …: Los argumentos que se pasarán a la función cuando se llame a la función vinculada.
Veamos un ejemplo para entenderlo mejor
const persona = {
nombre: "John",
saludar: function() {
console.log(`Hola, soy ${this.nombre}`);
}
};
const otraPersona = {
nombre: "Jane"
};
const funcionVinculada = persona.saludar.bind(otraPersona);
funcionVinculada(); // Output: Hola, soy Jane
En el ejemplo anterior, hemos usado bind() para crear una nueva función llamada funcionVinculada
con el valor de this vinculado al objeto otraPersona
. Cuando llamamos a funcionVinculada()
, hace referencia a otraPersona
como su valor de this.
Diferencias entre call(), apply() y bind()
Aunque call(), apply() y bind() se utilizan para cambiar el valor de this en una función, existen diferencias clave entre ellos:
- Sintaxis: La principal diferencia entre estos métodos es su sintaxis. call() y apply() son funciones que se llaman inmediatamente, mientras que bind() crea una nueva función que se puede llamar más tarde.
- Forma de pasar Argumentos: En call(), los argumentos se pasan individualmente, mientras que en apply(), los argumentos se pasan en un arreglo. En bind(), los argumentos se pasan de manera similar a call().
- Uso en situaciones diferentes: call() y apply() se utilizan principalmente cuando se sabe cuándo y cómo se llamará a la función con un valor de this específico y argumentos. Por otro lado, bind() se utiliza cuando se necesita crear una función con un valor de this vinculado para usarla posteriormente o cuando no se conoce el momento exacto de la llamada.
Escenarios de uso
A continuación, exploraremos algunos escenarios comunes en los que call(), apply() y bind() son útiles.
1. Cambiar el valor de «this» en métodos de objetos
Supongamos que tenemos un objeto que representa una persona y queremos crear otro objeto que represente a otra persona pero con el mismo método saludar()
:
const persona = {
nombre: "John",
saludar: function() {
console.log(`Hola, soy ${this.nombre}`);
}
};
const otraPersona = {
nombre: "Jane"
};
persona.saludar(); // Output: Hola, soy John
// Usando call() para cambiar el valor de "this" y reutilizar el método "saludar"
persona.saludar.call(otraPersona); // Output: Hola, soy Jane
En este caso, hemos reutilizado el método saludar()
usando call() para cambiar el valor de this dentro del método.
2. Llamar a una función con argumentos de un arreglo
Supongamos que tenemos una función que acepta tres argumentos y estos argumentos están almacenados en un arreglo:
function sumar(a, b, c) {
return a + b + c;
}
const arreglo = [2, 3, 5];
// Usando apply() para llamar a la función con los argumentos del arreglo
const resultado = sumar.apply(null, arreglo);
console.log(resultado); // Output: 10
En este caso, hemos utilizado apply() para pasar los argumentos de un arreglo a la función sumar()
.
3. Crear una nueva función con un valor de «this» vinculado
Supongamos que tenemos una función que forma parte de un objeto y queremos crear una nueva función que haga referencia a ese objeto específico como su valor de this:
const coche = {
marca: "Toyota",
modelo: "Corolla",
descripcion: function() {
console.log(`Este coche es un ${this.marca} ${this.modelo}`);
}
};
// Usando bind() para crear una nueva función vinculada al objeto "coche"
const descripcionDelCoche = coche.descripcion.bind(coche);
descripcionDelCoche(); // Output: Este coche es un Toyota Corolla
En este caso, hemos creado una nueva función descripcionDelCoche
usando bind() que hace referencia al objeto coche
como su valor de this. Esto nos permite utilizar la función en otro contexto sin perder la referencia al objeto original.
Conclusión
En resumen, call(), apply() y bind() son métodos fundamentales en Javascript que permiten a los desarrolladores manipular el valor de this en funciones. Call() y apply() se utilizan para llamar a una función inmediatamente con un valor de this y argumentos específicos, mientras que bind() crea una nueva función con un valor de this vinculado que se puede usar posteriormente.
Estos métodos son especialmente útiles cuando se trabaja con métodos de objetos, cuando se necesita pasar argumentos de un arreglo a una función o cuando se quiere crear una nueva función con un valor de this específico. Al dominar call(), apply() y bind(), los desarrolladores pueden escribir código más flexible y reutilizable, lo que lleva a una programación más eficiente y mantenible en Javascript.