call() apply() y bind()

facebook-svg gplus-svg twitter-svg

Los métodos call() apply() y bind() son muy importantes a la hora de trabajar con objetos en JavaScript. Los utilizamos para vincular funciones externas al objeto con cual queremos trabajar. Todos estos métodos son muy similares y hacen más o menos lo mismo, pero hay pequeñas diferencias.

Veamos un ejemplo:

En el HTML tenemos un elemento canvas


<canvas id="canvas"></canvas>

En el JavaScript primero inicializamos el canvas:


const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let cw = (canvas.width = 300);
let ch = (canvas.height = 300);

A continuación definimos algunas variables:


var color="tomato",
x= 100,
y= 100,
radio= 50;

También escribimos una función dibujar que dibuja un circulo en el canvas.


function dibujar(dx,dy) {
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(this.x + dx, this.y + dy, this.radio, 0, 2 * Math.PI);
    ctx.fill();
}

Por favor observe que la función dibujar utiliza variables como this.color, this.x, this.y . . . En este caso this.color, this.x, this.y. . . son variables que pertenecen al objeto window, o sea: las variables color, x, y y radio que ya hemos declarado.

See the Pen call apply bind #0 by Gabi (@enxaneta) on CodePen.

Pero hay situaciones cuando queremos dibujar más de una pelota, y queremos animar las pelotas, y cada pelota tiene su posición y su color y su velocidad en x e y, y a lo mejor queremos darlas unáa aceleración, y actualizarlas con cada fotograma. Y todo vuelve a ser muy complicado. La solución es organizarnos mejor, y para esto necesitamos utilizar objetos.

Podemos crear objetos literales así:


var pelota = {
    color: "tomato",
    x: 100,
    y: 100,
    radio: 50
  };

El método call()

Para poder dibujar la pelota necesitamos vincular la función dibujar al objeto pelota, porque queremos que this.color sea el color del objeto pelota etc . . . Lo podemos hacer utilizando el método call().

La sintaxis de call() es la siguiente:

nombreFuncion.call(objeto, argumentos);

Observe por favor que utilizamos el nombre de la función que queremos vincular ( sin paréntesis ) .

Retomando el ejemplo de arriba podemos escribir:

dibujar.call(pelota, 50, 50)

See the Pen call apply bind #1 by Gabi (@enxaneta) on CodePen.

El método apply()

El método apply() es muy parecido al método call(), con la única diferencia que tenemos que poner los argumentos en un array:

La sintaxis de apply() es la siguiente:

nombreFuncion.apply(objeto, [el, array, de, los, argumentos]);

Retomando el ejemplo anterior podemos escribir:

dibujar.apply(pelota, [50, 50])

See the Pen call apply bind #2 by Gabi (@enxaneta) on CodePen.

El método bind()

El método bind(), es bastante diferente ya que en lugar de vincular una función a un objeto, está creando una nueva función vinculada al objeto.  La sintaxis de bind() es:

let nuevaFuncion = nombreFuncion.bind(objeto);

Si volvemos al objeto anterior podemos escribir:

let dibujarPelota = dibujar.bind(pelota);

Esto crea una nueva función dibujarPelota() que podemos utilizar para . . .  dibujar la pelota:

dibujarPelota(50,50)

Alternativamente podemos abreviar estas dos líneas de código así:

dibujar.bind(pelota)(50,50);

See the Pen call apply bind #3 by Gabi (@enxaneta) on CodePen.