Инструкция function в JavaScript определяет функцию. Она имеет следующий синтаксис:
function имя_функции([арг1 [,арг2 [..., аргn]]]) { инструкции
}
Здесь имя_функции – это имя определяемой функции. Оно должно быть идентифи_ катором, а не строкой или выражением. За именем функции следует заключен_ ный в скобки список имен аргументов, разделенных запятыми. Эти идентифи_ каторы могут использоваться в теле функции для ссылки на значения аргумен_ тов, переданных при вызове функции.
Тело функции состоит из произвольного числа JavaScript_инструкций, заклю_ ченных в фигурные скобки. Эти инструкции не исполняются при определении функции. Они компилируются и связываются с новым объектом функции для исполнения при ее вызове с помощью оператора вызова (). Обратите внимание, что фигурные скобки – это обязательная часть инструкции function. В отличие от блоков инструкций в циклах while и других конструкциях, тело функции тре_ бует фигурных скобок, даже если оно состоит только из одной инструкции.
Определение функции создает новый объект функции и сохраняет объект в толь_ ко что созданном свойстве с именем имя_функции. Вот несколько примеров опреде_ лений функций:
function welcome() { alert("Добро пожаловать на мою домашнюю страницу!"); }
function print(msg) { document.write(msg, "<br>");
}
function hypotenuse(x, y) {
return Math.sqrt(x*x + y*y); // Инструкция return описана далее
}
function factorial(n) { // Рекурсивная функция if (n <= 1) return 1;
return n * factorial(n _ 1);
}
Определения функций обычно находятся в JavaScript_коде верхнего уровня. Они также могут быть вложенными в определения других функций, но только на «верхнем уровне», т. е. определения функции не могут находиться внутри инструкций if, циклов while или любых других конструкций.
114 Глава 6. Инструкции
Формально function не является инструкцией. Инструкции приводят к некото_ рым динамическим действиям в JavaScript_программе, а определения функций описывают статическую структуру программы. Инструкции исполняются во время исполнения программы, а функции определяются во время анализа или компиляции JavaScript_кода, т. е. до их фактического исполнения. Когда син_ таксический анализатор JavaScript встречает определение функции, он анали_ зирует и сохраняет (без исполнения) составляющие тело функции инструкции. Затем он определяет свойство (в объекте вызова, если определение функции вло_ жено в другую функцию; в противном случае – в глобальном объекте) с именем, которое было указано в определении функции.
Тот факт, что функции определяются на этапе синтаксического анализа, а не во время исполнения, приводит к некоторым интересным эффектам. Рассмотрим следующий фрагмент:
alert(f(4));
// Показывает 16. Функция f() может быть
вызвана до того,
// как она определена.
var f = 0;
// Эта инструкция переписывает содержимое свойства f.
function f(x) { // Эта "инструкция" определяет функцию f
до того,
return x*x; // как будут выполнены приведенные ранее
строки.
}
alert(f);
// Показывает 0. Функция f() перекрыта переменной f.
Такие необычные результаты возникают из_за того, что функция определяется не в то время, в которое определяется переменная. К счастью, подобные ситуа_ ции возникают не очень часто.