2010-08-07 8 views
5

¿Cuál es la forma más corta (caracteres) de crear un alias de "nueva función"?Forma más corta de crear un alias de "nueva función" en javascript

Básicamente esto es para código de golf y código minifying beyond reason. Así que cuando usted normalmente escribiría:

a=function(a,b,c){return a+b+c;} 

Se puede escribir algo así como (también de dejar que la palabra clave abstracto de devolución, así como con la variable global R):

a=$("a,b,c","R=a+b+c") 
a=$(a,b,c){R=a+b+c} 

(No estoy seguro si el segundo es posible .)

Para el primer ejemplo de lo mejor que he llegado con es:

$=function(a,b){return new Function(a,"R=0;"+b+";return R")} 

Ambos tamaños (uso, declaración) son importantes, pero el tamaño de uso es más importante.

+0

¿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

+0

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

+0

@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

Respuesta

18

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.

+0

+1 para "expresiones lambada". (Uno dos tres, ¡oye!) –

1

Para expresiones simples, se puede utilizar:

function L(a,x){return new Function(a,'return '+x)} 

Uso:

n=L('a,b,c','a+b+c'); 
0

Aquí hay una variante que tiene una sobrecarga mayor, pero guarda un carácter por definición de la función. "@" se reemplazará por "devolver".

$=function(a,b){return new Function(a,b.replace(/@/g,"return "))} 
a=$("a,b,c","@a+b+c") 
0

Es posible conseguir kilometraje de algo tonto como:

eval("t=Fa+b};t(1,2)".replace("F", "function(a,b){return ")) 
0

Su código: a=function(a,b,c){return a+b+c;}

código acortada: a=(a,b,c)=>a+b+c

La declaración de la función más corto posible en js es 4 caracteres

Ejemplo:_=>1

Cuestiones relacionadas