buenas...
veo que el tema de
apply te trae loco desde un
tema que se formulo recientemente.
apply al igual que
call, lo que hace es invocar una funcion como si fuese propia de otro objeto. o dicho de otro modo,
call y apply cambia el propietario de la funcion por otro objeto. de modo que cada vez que en la funcion se utiliza la referencia
this, dicha referencia representa el nuevo objeto. veamos un ejemplo:
Código:
var foo = {fn: function(){
console.log(this.bar);
// console.log es una funcion de las consolas javascript para mostrar resultado en la consola ;
}, bar: true};
var boo = {bar: 'string'};
foo.fn.call(boo);
foo.fn.apply(boo);
en este ejemplo, notese que el objeto
boo no contiene metodo pero tiene la propiedad
bar al igual que el objeto
foo. adiconalmente, notese que la funcion
fn utiliza la referencia
this para acceder al objeto que contiene la funcion. ahora, para invocar esa funcion como si fuese una funcion de
boo, tendriamos que utilizar
call o
apply. si observas la consola de javascript, veras que la salida fue
'string'.
¿por qué existe dos funciones para el mismo propósito, o cual es la diferencia entre ellos? para ello, tendrias que ver la sipnosis de cada funcion.
Código:
fn.apply(object, array);
fn.call(object, arg1, ..., argN);
apply recibe dos argumentos, el objeto al cual se va aplicar la funcion y un array de valores. dicho array se tomaran como argumentos para la funcion aplicada al objeto. en contraste,
call puede recibir uno o mas argumentos, siendo el primero el objeto y el resto los argumentos para la funcion aplicada al objeto.
Código:
var Rate = {
fixed: 1.07,
calc: function(value, add){
return this.fixed * value + add;
}};
var rate = {
fixed: 1.37
};
console.log(Rate.calc.call(rate, 3.14, 7));
console.log(Rate.calc.apply(rate, [2.3, 1.2]));
en este corto ejemplo, notese que el metodo
calc recibe dos argumentos:
value, add. al aplicar el metodo a otro objeto debemos tambien pasarle los parametros el cual lo puedes observar en
call y apply.
proximo punto, ¿por que agregue dos ceros al inicio del array? como quizas sabras,
splice modifica los arrays, ya sea agregar o eliminar elementos. el primer argumento de
splice se refiere a partir de cual elemento del array se va a modificar, el segundo argumento es un conteo a partir del primer argumento, y los subsiguientes argumentos son los valores que se van a introducir al array. como veras, en el metodo del prototipo, la idea es restaurar el array con el original. no puedo utilizar
concat porque dicho metodo no modifica el array, solo devuelve uno nuevo. adicional, tampoco puedes asignar un valor a
this. o sea, ninguna de las siguientes lineas funciona.
Código:
this = this.clone.concat();
this = this.clone.slice(0, this.clone.length);
// notese que dice slice, no splice ;
la unica alternativ que me permite modificar el array original es
splice o recorrer el clon con un bucle pero como el tema en particular es con
splice entonces dejare a un lado el bucle. si hiciera lo siguiente me devuelve un resultado incorrecto:
Código:
this.splice(0, 0, this.clone);
// el array tendria como elemento otro array ;
// por ejemplo, [].splice(0,0, [0,1,2,3]) resultaria como ;
// [[0,1,2,3]] y lo que quiero lograr es [0,1,2,3] ;
por tanto, la solucion es hacer que
splice introduzca los elementos al array. para ello me valgo de
splice con
apply. de modo que si no agrego al inicio los dos ceros,
apply aplicaria la funcion de forma similar a lo siguiente.
Código:
this.clone = [0,1,2,3]; // asumiendo que dicho array es la copia ;
this.splice.apply(this, this.clone);
// la linea anterior seria similar a ;
this.splice(0,1,2,3);
notese el problema de la ultima linea, los primeros dos elementos del array estarian indicando a
splice que debe comenzar por el primer elemento del array original y va a remover un solo elemento del original. el tercer argumento en adelante vendrian siendo los valores a introducir al array. por tanto, el resultado final en un array vacio seria
[2,3]. ahi es donde juega el papel importante de los ceros introducidos al clon. es para que
splice pueda introucir correctamente los valores del clon en el array original.
como observacion adicional,
call no era apropiado en la solucion porque como iba a enumerar los argumentos a partir del array. de modo que
apply hace esa tarea por mi.
hasta aqui llega la leccion de hoy...
saludos!