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 valor this que es thisObj

  • arg1, arg2, son los argumentos adicionales que tomará la función foo ( 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 argumento

  • apply — 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 de this 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