Є деякі речі, які неможливо зробити в JS без Eval подібних функцій ( eval
, Function
, і , можливо , більше).
Візьмемо apply
для прикладу. Його легко використовувати під час звичайних функціональних дзвінків:
foo.apply(null, [a, b, c])
Але як би ви це зробили для об’єктів, які ви створюєте за допомогою нового синтаксису?
new Foo.apply(null, [a, b, c])
не працює, не має подібних форм.
Але ви можете подолати це обмеження через eval
або Function
(я використовую Function
в цьому прикладі):
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);
};
}) ();
Приклад:
Foo.New.apply(null, [a, b, c])
;
Звичайно, ви можете вручну побудувати функції, які Function.prototype.New
використовує, але це не тільки цей багатослівний і незграбний характер, він (за визначенням) повинен бути кінцевим. Function
дозволяє коду працювати для будь-якої кількості аргументів.
eval
великих фрагментів коду, як люблять такі програми, як JSPacker? JSPacker + gzip зазвичай призводить до менших розмірів файлів, ніж будь-яке рішення самостійно, але, як ви правильно зазначаєте, він по суті запускає компілятор двічі на один і той самий фрагмент коду, а також накладні витрати, щоб зробити заміну рядків.