Są pewne rzeczy, które są niemożliwe do zrobienia w JS bez funkcji eval (podobny eval
, Function
i być może więcej).
Weźmy apply
na przykład. Jest łatwy w użyciu, gdy używasz go do zwykłych wywołań funkcji:
foo.apply(null, [a, b, c])
Ale jak byś to zrobił dla obiektów tworzonych za pomocą nowej składni?
new Foo.apply(null, [a, b, c])
nie działa, ani nie robi podobnych form.
Ale możesz obejść to ograniczenie za pomocą eval
lub Function
(używam Function
w tym przykładzie):
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);
};
}) ();
Przykład:
Foo.New.apply(null, [a, b, c])
;
Oczywiście można ręcznie budować używane funkcje Function.prototype.New
, ale nie tylko jest to pełne i niezgrabne, ale (z definicji) musi być skończone. Function
umożliwia działanie kodu dla dowolnej liczby argumentów.
eval
tworzenia dużych fragmentów kodu tak, jak lubią aplikacje takie jak JSPacker? JSPacker + gzip zwykle skutkuje mniejszymi rozmiarami plików niż którekolwiek z rozwiązań, ale jak słusznie zauważyłeś, zasadniczo uruchamia kompilator dwa razy na tym samym fragmencie kodu, a także narzuca pewne koszty zastępowania łańcucha.