No creo new Function()
es de uso viable para la mayoría de las funciones, incluso sin los problemas de rendimiento porque a diferencia de function() {}
no se crea ningún cierre. La función compilada solo tendrá acceso a su propio alcance local y al objeto global. Piense en eso por un segundo. Javascript sin cierres es como Java sin clases o C sin punteros. Claramente, todo se rompería.
De todos modos, si solo tiene la intención de utilizar este alias para expresiones cortas de lambada que no necesitan clousers, una forma obvia de hacer las cosas aún más escuetas es dejar de desacelerar los parámetros. Simplemente asumen que a = arguments[0]; b = arguments[1];
etc ...
$=function(b){return new Function('a,b,c,d,e,f,g,h,i,j', b);};
Otra forma sería la de devolver automáticamente el valor de la última expresión, en lugar de tener que declararse explícitamente
$=function(body) {
return function(a,b,c,d,e,f,g,h,i,j) { return eval(body); };
};
horripilante ¿verdad? Esto funciona porque eval()
... bien devuelve el valor de la última expresión evaluada. No es necesario return
. Por supuesto, este método tiene un impacto aún mayor en el rendimiento, ya que el código en body
se reevalúa cada vez que se llama a la función, mientras que con new Function
el código es (o debería ser) solo compilado una vez.
De todas formas el rendimiento será represado, con el método anterior declaración de la función se ha reducido a esta
var myeyes = $('a+b+c');
alert(myeyes(1,2,3)); //6
Purdy eh? Aún así, creo que se vería mejor así
'a+b+c'
Parece una cadena de si? Bien...se trata de una picadura, pero en las manos de la función correcta, podría ser evaluado como si fuera un lleno en el literal de la función
//Lets just assume that IE does not exist mmkay?
var funcs = ['map', 'filter', 'every', 'some'];
for (var i=0; i<funcs.length; i++) {
(function() {
//Store original function
var name = funcs[i]
var _super = Array.prototype[name];
Array.prototype[name] = function() {
//$ !== jQuery
if (typeof arguments[0] == 'string') arguments[0] = $(arguments[0]);
return _super.apply(this, arguments);
};
}());
}
Ahora se puede escribir
[1,2,3,4,5].map('a*a');
en lugar de
[1,2,3,4,5].map(function(a){return a*a;});
que es incluso mejor que la expresión de cierre de Firefox
[1,2,3,4,5].map(function(a) a*a);
Pruébalo aquí: http://jsbin.com/iyogu3/edit
Si tan sólo pudiéramos escribir en realidad expresiones de función como esta sin recurrir al monstruo eval. Realmente, uno de mis problemas principales con la sintaxis de Javascript es el requisito de correo no deseado function(){}
en todo su código. Algún tipo de sintaxis literal de la función de taquigrafía (que no sea el cierre de expresiones a medio hacer antes mencionado) que se interpretó de la misma manera que un literal de función verbosa regular, ayudaría mucho a hacer que mi código parezca un poco menos ridículo. Y podría ayudar a minificar un pequeño bit también.
¿Qué pasa con el tiempo de ejecución? Cualquier cosa que incluya un pase de interpretación adicional (como su ejemplo, ya que su función es una cadena) es probable que tome mucho tiempo. Tanto que arruinas la ganancia en el tiempo de descarga (que probablemente sea de unas pocas docenas de milisegundos). – MvanGeest
Como dije "más allá de la razón". Se trata más de tratar de minimizar los personajes que intentar obtener un beneficio real de ello. – Egon
@egon: cuál quieres minimizar, la parte 'a = $ (" a, b, c "," R = a + b + c ")' o la función '$ = (a, b) {return nueva función (a, "R = 0;" + b + "; return R")} '¿parte o el total? – kennytm