Skip to content

Instantly share code, notes, and snippets.

@joseanpg
Created August 21, 2011 09:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joseanpg/1160391 to your computer and use it in GitHub Desktop.
Save joseanpg/1160391 to your computer and use it in GitHub Desktop.
GEJS-4 memorizaParametro (aplicación parcial)
Function.prototype.memorizaParametro = function(parametro) {
var funcionSobreLaQueSeEjecuto_memorizaParametro = this;
return function() {
var argsArray = Array.prototype.slice.call(arguments,0);//Convertimos en array
argsArray.unshift(parametro);
return funcionSobreLaQueSeEjecuto_memorizaParametro.apply(this,argsArray);
}
}
//Primer ejemplo: uso puramente funcional
var alfa = function(uno,dos,tres) {
var r = uno+dos+tres;
console.log("Primer parametro: "+uno)
console.log("Resultado: "+r);
return r;
}
var beta = alfa.memorizaParametro(7);//Partial application
alfa(7,2,3); //Primer parametro 1, 6
beta(2,3); //Primer parametro 7, 12
//Segundo ejemplo: "metodo" de un objeto (usando this)
var bob = {
nombre:'Bob Esponja',
cocinar:function(receta,numero){
var texto = '\u00A1 Yo '+this.nombre+' voy a preparar '+numero+' '+receta+' !';
console.log(texto);return texto;
}
}
bob.cocinar('pizzas',20); //¡ Yo Bob Esponja voy a preparar 20 pizzas !
console.log('\u00A1 Ese no es tu trabajo chico !');
bob.cocinar = bob.cocinar.memorizaParametro('cangreburguers'); //Partial application
bob.cocinar(20); //¡ Yo Bob Esponja voy a preparar 20 cangreburguers !
@boton
Copy link

boton commented Aug 23, 2011

Una duda:
hace falta realmente convertir el arguments a array? No nos vale que sea un 'Array-like Object' (o como se diga)

Function.prototype.memorizaParametro = function(param) {
  var func = this;
  return function() {
    Array.prototype.unshift.call(arguments,param);
    return func.apply(this,arguments);
  };
};

Para mi el ejercicio ha sido entender esta linea en concreto Array.prototype.slice.call(arguments,0); y me ha gustado entenderla por fin, gracias por el ejercicio @joseanpg :)

Consulté:
https://developer.mozilla.org/en/JavaScript/Reference/functions_and_function_scope/arguments
http://hustoknow.blogspot.com/2010/10/arrayprototypeslicecallarguments.html
http://www.etnassoft.com/2011/01/21/el-objeto-arguments-en-javascript/

@joseanpg
Copy link
Author

¡Interesantísima cuestión! Hay varios motivos por los cuales no se suele utilizar tu versión, que por otra parte debe funcionar correctamente.

Como seguramente sabrás arguments es un objeto interno acoplado con los parametros de la función de manera que si tocas el valor de un parámetro se actualiza el correspondiente elemento de arguments y viceversa, esto plantea dos problemas:

  • Es un objeto relativamente pesado con una conjunto de funciones que le permiten mantener el acoplamiento. Aquí ocurre algo similar a los pseudo-arrays obtenidos con getElementsByTagName, cuanto antes los conviertas en un auténtico y simple array mejor.
  • Por otra parte el pasar el arguments permite jugar sucio a la función que lo recibe violando el Principle of Least Authority (POLA): la receptora toca un elemento del arguments recibido y está alterando, por la cara, el correspondiente argumento de la función que la invocó, lo cual es una barbaridad, sobre todo en un entorno abierto como es la web con los scripts-tags trayendo código de todas partes. En este caso no importa, ya que la función a la que se pasará el arguments está en Taill Call Position. Estamos a salvo por este lado pero ...

... Pero existe otro peligro de violación de POLA: arguments tiene una propiedad callee que permitiría a la función receptora invocar a la función que la llamó. Y peor aún, en muchas implementaciones mediante arguments es posible acceder a caller y llamar a la del nivel superior.

Por estos motivos no es buena práctica pasar arguments y se copian sus elementos naturales en un array normal.

Por cierto, el Strict Mode de ECMAScript 5 carga a arguments de limitaciones para evitar todas estas posibilidades desagradables :)

@juandopazo
Copy link

Para molestar a @joseanpg te voy a recomendar este link http://ejohn.org/apps/learn/#2

@boton
Copy link

boton commented Aug 23, 2011

@joseanpg muchas gracias por la explicación, así da gusto preguntar :)
@juandopazo gracias por el link, lo conocía (tengo el libro en preorder) pero me falta estudiar un poco más antes de pegarme con el juguete de Resig ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment