Function call y apply

En Javascript realmente todas las funciones son métodos de algún objeto. Si no hay un objeto específico que posea a una función, entonces el propietario será el objeto global Object.

var cuadro = {

   alto = 10;

   base = 20;

   area = function(){return this.alto*this.base}

}

console.log(cuadro.area()); //200

En este ejemplo el objeto propietario de la función (método) area es cuadro. Para ejecutar esta función lo tenemos que hacer desde el objeto cuadro.

Dentro del método el código puede hacer referencia a su objeto propietario mediante la variable this. Esta variable equivale a invocar al objeto donde está el método. En el ejemplo this es cuadro

El objeto Function posee dos métodos para modificar este comportamiento: permiten ejecutar el método de un objeto con otro objeto como propietario. Son

  • call(nuevo_this, arg, arg, arg...): permite suplantar this con nuevo_ this y puede enivar además un número  variable de argumentos.
  • aply(nuevo_this, arg): permite suplantar this con nuevo_this y puede enviar además un array con argumentos

Como ves son idénticas solo cambia la forma en que se envián los argumentos

Cuadro = function(a,b){

this.alto=a;

this.base = b;

this.area = function(){return this.alto*this.base}

}

var sala = new Cuadro(0,0);

var salon = {alto:10, base:20};

sala.area.call(salon)

En este ejemplo vemos que el objeto salon no posee métodos, el objeto sala tiene el método area. Observa como se usa el método call de la función sala.area para que se ejecute con el objeto salon. Si cambias call por apply verás que funciona exactamente igual

El mecanismo es muy simple. Cuando se ejecuta un método el objeto this representa al propietario, con call() se cambia esto, y el objeto this apunta al argumento pasado con call

Como mínimo call debe pasar un argumetno para suplantar a this, pero puede pasar más argumentos si la función llamada posee parámetros.

function Plantas(nombre){

     this.nombre = nombre;

     this.sitio = this.categoria == "flor"?"jardin":"huerto" }

var Flores = function(nombre){

     this.categoria="flor";

     Plantas.call(this, nombre)

}

var Verduras = function(nombre){

     this.categoria="huerta";

     Plantas.apply(this, [nombre])

}

rosa = new Flores('rosa');

console.log(rosa);

pimiento = new Verduras('pimiento');

console.log(pimiento);

En este caso se ha usado una función para nombrar y situar las plantas dependiendo de si son o no flores.

En la primera llamada el objeto this dentro de Plantas es el objeto rosa: rosa usa el constructor Flores que llama a la función Plantas con el mismo como agumento y nombre

En la segunda llamada el objeto this dentro de Plantas es el objeto pimiento: pimiento usa el constructor Verduras que llama a la función Plantas con el mismo como argumento y nombre

Es como si la función Plantas fuera un método del objeto Flores y del objeto Verduras, pero solo se ha escrito una vez.

Como ves se puede usar apply, cambiando call(this, nombre) por apply(this, [nombre]), de esta manera el argumento que qconpña a nuevothis va en un array.

Estos métodos sirven, por ejemplo, cuando varios objetos tienen métodos similares, solo es necesario escribirlos una vez y luego usarlos con el mecanismo de call()/apply()

Esto permitiría tener un inicialziador común para objetos diferentes evitando así duplicidad de código.

scripts