Há algumas coisas que são impossíveis de fazer em JS sem uma função eval-like ( eval, Functione talvez mais).
Tome applypor 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 evalou Function(eu uso Functionneste 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.Newusa, mas não apenas isso é detalhado e desajeitado, mas (por definição) precisa ser finito. Functionpermite que o código funcione para qualquer número de argumentos.
evalgrandes 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.