Call, Apply y Bind
En simples palabras todos estos métodos se usan para cambiar el valor del contexto(this) dentro de una función, es decir, podemos enviarle un contexto(this) al momento de la llamada a una función.
Call
Usando el método call
, podemos invocar una función, pasando un valor que será tratado como this
dentro de ella.
const obj = {
myName: "khriztianmoreno",
printName: function () {
console.log(this.myName);
},
};
obj.printName(); // khriztianmoreno
const newObj = {
myName: "mafeserna",
};
obj.printName.call(newObj); //mafeserna
En el ejemplo anterior, estamos invocando el método call
en la función printName
al pasar newObj
como parámetro, por lo que ahora this
dentro de printName
apunta a newObj
, por lo tanto, this.myName
imprime mafeserna
.
Argumentos
function foo(param1, param2) {}
foo.call(thisObj, arg1, arg2);
dónde:
foo
es la función que estamos invocando al pasar el nuevo valorthis
que esthisObj
arg1
,arg2
, son los argumentos adicionales que tomará la funciónfoo
(param1
=arg1
,param2
=arg2
)
Apply
La función apply
es muy similar a la función call
. La única diferencia entre call
y apply
es la diferencia en cómo se pasan los argumentos.
call
— pasamos argumentos como valores individuales, comenzando desde el segundo argumentoapply
— los argumentos adicionales se pasarán como un arreglo
function sayHello(greet, msg) {
console.log(`${greet} ${this.name} ! ${msg}`);
}
const obj = {
name: "khriztianmoreno",
};
// Call
sayHello.call(obj, "Hello", "Good Morning");
// Hello khriztianmoreno ! Good Morning
// Apply
sayHello.apply(obj, ["Hello", "Good Morning"]);
// Hello khriztianmoreno ! Good Morning
en el ejemplo anterior, tanto el método call
como apply
en la función sayHello
están haciendo lo mismo, la única diferencia es cómo estamos pasando argumentos adicionales.
Bind
A diferencia de los métodos call
y apply
, bind
no invocará la función directamente, sino que cambiará el valor this
dentro de la función y devolverá la instancia de la función modificada.
Podemos invocar la función devuelta más tarde.
function sayHello() {
console.log(this.name);
}
const obj = { name: "khriztianmoreno" };
// it won't invoke, it just returns back the new function instance
const newFunc = sayHello.bind(obj);
newFunc(); // khriztianmoreno
pasando argumentos adicionales:
pasar argumentos adicionales en bind
funciona de manera similar al método call
, podemos pasar argumentos adicionales como valores individuales a partir del segundo argumento del método bind
.
function sayHello(greet) {
console.log(`${greet} ${this.name}`);
}
const obj = { name: "khriztianmoreno" };
const newFunc = sayHello.bind(obj, "Hello");
newFunc(); // Hello khriztianmoreno
En el caso del método bind
, podemos pasar argumentos adicionales de dos formas:
Al llamar al método
bind
en sí mismo, podemos pasar argumentos adicionales junto con el valor dethis
a esa función.Otra forma es que podemos pasar argumentos adicionales mientras invocamos la función de retorno del método
bind
.
Podemos seguir cualquiera de las formas anteriores y funciona de manera similar sin ninguna diferencia en la funcionalidad.
function sayHello(greet) {
console.log(`${greet} ${this.name}`);
}
const obj = { name: "khriztianmoreno" };
const newFunc1 = sayHello.bind(obj, "Hello");
newFunc1(); // Hello khriztianmoreno
const newFunc2 = sayHello.bind(obj);
newFunc2("Hello"); // Hello khriztianmoreno
NOTA: si no pasamos ningún valor o pasamosnull
mientras llamamos a los métodos call
, apply
, bind
, entonces esta
función interna de llamada apuntará al objeto global
.
function sayHello() {
// executing in browser env
console.log(this === window);
}
sayHello.call(null); // true
sayHello.apply(); // true
sayHello.bind()(); // true
No podemos usar los métodos call
, apply
y bind
en las funciones flecha para cambiar el valor de this
, porque las funciones de flecha no tienen su propio contexto this
.
El this
dentro de la función de flecha apuntará a la función externa/principal en la que está presente.
Por lo tanto, aplicar estos métodos en la función de flecha no tendrá ningún efecto.
Last updated