С самого начала нужно подразделить эти способы на две категории: Function Declaration (объявление функции) и Function Expression (функциональное выражение).
Также важно примерно представлять, как работает интерпретатор JavaScript:
- Сначала интерпретатор считывает код программы до конца, производя объявления (но не инициализацию переменных), записывая в динамическую память структуру объектов (в частности, функций).
- Затем интерпретатор начинает выполнять второй проход по коду: строку за строкой, уже производя вычисления и инициализируя переменные.
Итак, рассмотрим основные способы создания функций в JavaScript.
1. Используя конструктор 'new Function' (Function constructor).
Синтаксис:
new Function ("arg1,...argN","Тело функции")
или
new Function ("arg1",..."argN","Тело функции")
Пример:
- Код: Выделить всё
var f1 = new Function ("x,y","var x1 = x; var y1 = y; alert(x1*y1)");
f1(2,3); // 6
var f2 = new Function ("x","y","var x1 = x; var y1 = y; alert(x1*y1)");
f2(2,3); // 6
или для разминки (практического смысла нет):
- Код: Выделить всё
new Function ("x,y","var x1 = x; var y1 = y; alert(x1*y1)")(2,3); // 6
// можно и так:
Function ("x,y","var x1 = x; var y1 = y; alert(x1*y1)")(2,3); // 6
Нужно сказать, что, вообще, не рекомендется использовать для создания функций конструктор new Function. Т. к. интерпретатор при обращении к такой функции каждый раз её парсит.
2. Декларативное создание функции (function declaration).
Синтаксис:
function name([парам1,[парам2,[...,парамN]]]) { Тело функции; }
Пример:
- Код: Выделить всё
f1(2,3) // 6
// ........
function f1(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}
Обратите внимание, что в случае такого объявления мы можем вызвать функцию в скрипте до её объявления в тексте. Как я писал выше, интерпретатор к моменту исполнения программы, уже сделал один проход и уже имеет функцию f1 в своей памяти.
3. Функциональное выражение (function expression).
Синтаксис:
[оператор/контекст]function ([парам1[,парам2,[...,парамN]]]) { Тело функции; }
(Обратите внимание, что у функции может не быть имени. Анонимную (безымянную) функцию мы можем присвоить переменной или выполнить на месте, используя оператор '()' после фигурных скобок.)
Функциональное выражение можно задать даже так:
[оператор/контекст]function name([парам1[,парам2,[...,парамN]]]) { Тело функции; }
(если интерпретатор истолкует это не как декларирование, а как часть выражения, например, заключив декларирование функции в группирующие скобки).
Примеры:
- Код: Выделить всё
f1(2,3) // Ошибка! Error: TypeError: f1 is not a function
// ........
var f1 = function (x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}
f1(2,3) // 6
Как видим, в первой строке кода переменная f1 еще не инициализирована, поэтому интерпретатор выдает ошибку, типа какая функция, вы чо??
А вот ещё примеры функциональных выражений:
- Код: Выделить всё
// Именованное функциональное выражение
var f1 = function fName(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}
f1(2,3) // 6
fName(2,3) // Ошибка! Error: fName is not defined
Зато 'fName' доступно внутри тела самой функции.
Рассмотрим несколько примеров вызова функции на месте:
- Код: Выделить всё
// Так нельзя!
function fName(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}(2,3)
// Так можно
+function fName(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}(2,3)
// Так можно
(function fName(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
})(2,3)
// или
(function fName(x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}(2,3))
// Так можно (безымянная функция)
(function (x,y){
var x1 = x; var y1 = y; alert(x1*y1)
})(2,3)
// или
(function (x,y){
var x1 = x; var y1 = y; alert(x1*y1)
}(2,3))
Скобки вокруг функций — это оператор группировки, который превращает объявление функции в функциональное выражение. А круглые скобки в конце — это оператор вызова функции.
Эта статья будет полезна для перехода к следующей теме: Замыкания в JavaScript, функции и область видимости. Продолжение скоро последует..