Как уже говорилось ранее, функции обычно определяются с помощью ключево_ го слова function либо в форме определения функции, либо посредством функ_ ционального литерала. Однако помимо этого существует возможность создания функций с помощью конструктора Function(). Создание функций с помощью конструктора Function() обычно сложнее, чем с помощью функционального ли_ терала, поэтому такая методика распространена не так широко. Вот пример соз_ дания функции подобным образом:
var f = new Function("x", "y", "return x*y;");
Эта строка создает новую функцию, более или менее эквивалентную функции, определенной с помощью более привычного синтаксиса:
function f(x, y) { return x*y; }
Конструктор Function() принимает любое количество строковых аргументов. По_ следний аргумент – это тело функции. Он может содержать произвольные Java_ Script_инструкции, отделенные друг от друга точками с запятой. Все остальные аргументы конструктора представляют собой строки, задающие имена парамет_ ров определяемой функции. Если вы определяете функцию без аргументов, кон_ структору передается только одна строка – тело функции.
Обратите внимание: конструктору Function() не передается аргумент, задающий имя создаваемой им функции. Неименованные функции, созданные с помощью конструктора Function(), иногда называются анонимными функциями.
Есть несколько моментов, связанных с конструктором Function(), о которых сле_ дует упомянуть особо:
• Конструктор Function() позволяет динамически создавать и компилировать функции во время исполнения программы. В чем_то он напоминает функцию eval() (за информацией обращайтесь к третьей части книги).
164 Глава 8. Функции
• Конструктор Function() компилирует и создает новую функцию при каждом вызове. Если вызов конструктора производится в теле цикла или часто вызы_ ваемой функции, это может отрицательно сказаться на производительности программы. В противовес этому функциональные литералы или вложенные функции, находящиеся внутри цикла, не перекомпилируются на каждой итерации, а кроме того, в случае литералов не создается новый объект функ_ ции. (Хотя, как уже отмечалось ранее, может создаваться новое замыкание, хранящее лексический контекст, в котором была определена функция.)
• И последний очень важный момент: когда функция создается с помощью конструктора Function(), не учитывается текущая лексическая область види_ мости – функции, созданные таким способом, всегда компилируются как функции верхнего уровня, что наглядно демонстрируется в следующем фраг_ менте:
var y = "глобальная";
function constructFunction() { var y = "локальная";
return new Function("return y"); // Не сохраняет локальный контекст!
}
// Следующая строка выведет слово "глобальная", потому что функция,
// созданная конструктором Function(), не использует локальный контекст.
// Если функция была определена как литерал,
// эта строка вывела бы слово "локальная".
alert(constructFunction()()); // Выводит слово "глобальная"