Há algumas coisas que são impossíveis de fazer em JS sem uma função eval-like ( eval
, Function
e talvez mais).
Tome apply
por exemplo. É fácil de usar ao usá-lo em chamadas de funções comuns:
foo.apply(null, [a, b, c])
Mas como você faria isso para objetos que você está criando através de nova sintaxe?
new Foo.apply(null, [a, b, c])
não funciona, nem formas semelhantes.
Mas você pode contornar essa limitação via eval
ou Function
(eu uso Function
neste exemplo):
Function.prototype.New = (function () {
var fs = [];
return function () {
var f = fs[arguments.length];
if (f) {
return f.apply(this, arguments);
}
var argStrs = [];
for (var i = 0; i < arguments.length; ++i) {
argStrs.push("a[" + i + "]");
}
f = new Function("var a=arguments;return new this(" + argStrs.join() + ");");
if (arguments.length < 100) {
fs[arguments.length] = f;
}
return f.apply(this, arguments);
};
}) ();
Exemplo:
Foo.New.apply(null, [a, b, c])
;
Obviamente, você pode criar manualmente as funções que Function.prototype.New
usa, mas não apenas isso é detalhado e desajeitado, mas (por definição) precisa ser finito. Function
permite que o código funcione para qualquer número de argumentos.
eval
grandes pedaços de código da maneira que aplicativos como o JSPacker gostam? O JSPacker + gzip geralmente resulta em tamanhos de arquivo menores do que qualquer solução por si só, mas como você corretamente aponta, ele essencialmente está disparando um compilador duas vezes no mesmo pedaço de código, além de algumas despesas gerais para fazer substituições de cadeias.