Простейший способ создать функцию — использовать следующий синтаксис:
function runMe() {
// тело функции
}
Такое объявление функции называется Function Expression. Особенностью такого объявления является то, что функция определяется на этапе анализа кода, в результате чего функцию можно использовать в любом месте программы.
runMe();// можно вызывать до определения функции
function runMe() {
// код
}
Правила именования функций такие же, как для переменных. Рекомендуется использовать глаголы для названий функций.
Объявить функцию можно просто присвоив значение переменной:
var executeMe = function () {
// код
}
В этом случае функцию можно будет вызвать только ниже её определения:
executeMe();// Ошибка! Функция не определена
var executeMe = function () {
// код
};
executeMe();// Ок, функция определена и она выполнится
Чаще всего результат выполнения функции зависит от каких-то других переменных. Такие переменные передаются в функцию в качестве параметров:
function shoMessage(message) {
alert(message);
}
shoMessage("Hello there!");
Переменных может быть несколько, в этом случае они разделяются запятой:
function shoMessage(author, time, message) {
alert('[' + time + '] ' + author + ': ' + message);
}
shoMessage("Basil", "00:42", "Hello there!");
Кроме того функция может возвращать результаты своих вычислений для дальнейшего использования. Возврат значения осуществляется с помощью оператора return:
function dbl(n) {
return 2 * n;
}
var doubled = dbl(2);
alert(doubled);
Если return в функции не задан или после return ничего нет, то функция возвращает undefined.
Также для создания функции может использоваться следующий синтаксис:
var killMe = new Function (
'a, b', // параметры функции
'return a + b;' // код функции
);
Такую запись используют в тех случаях, когда тело функции генерируется динамически и может зависить от каких либо условий. Но рекомендуется не использовать этот синтаксис, а проверку таких условий осуществлять прямо в теле функции.
Переменные внутри функции, объявленные с помощью var, имеют локальную область видимости. Если за пределами функции есть переменная с таким же именем, то внутри функции бцдет использоваться её локальная переменная. Если Задать переменную без var, то создастся глобальная переменная.
var a = 1,
b = 2;
function rotate() {
var a = 3; // локальная переменная не изменит глобальной
b = 4; // без var меняем глобальную переменную
var с = 5; // локальная переменная не видна за пределами функции
d = 6; // без var создали новую глобальную переменную
}
rotate();
alert(a); // 1
alert(b); // 4
alert(c); // Error: c is not undefined
alert(d); // 6
Рекомендуется без особой необходимости не использовать глобальные переменные внутри функции.
Функция в своих вычислениях может использовать результат выполнения самой себя, но с другими параметрами. Такая функция называется рекурсивной.
Например, чтобы найти факториал числа 7 нужно 7 умножить на факториал числа 6. Факториал 6, в свою очередь, находится как произведение 6 на факториал 5 и т.д. Факториал 1 равен 1. Таким образом, факториал можно рассчитать с помощью рекурсивной функции:
function factorial(n) {
if(n <= 1) {
return 1; // базовый случай, когда углубляться дальше не надо
} else {
return n * factorial(n - 1);
}
}
alert(factorial(6));
Для того, чтобы рекурсивные функции можно было определять в виде функциональных выражений был создан специальный синтаксис - именованные функциональные выражения.
Имя функционального выражения доступно только внутри самой функции и не может быть перезаписано. Такая запись позволяет присваить функцию переменной с любым именем, не меняя содержимае функции, которая всегда сможет вызывать себя благодаря внутреннему имени.
var factorial = function f(n) {
return n==1 ? 1 : n*f(n-1);
}
var fctrl = factorial; // копируем функцию в другую переменную
factorial(6); // работает как обычное функциональное выражение
f(6); // Error: f is not defined
fctrl(6); // работает, функция скопировалась
В некоторых случаях есть необходимость прозвести некоторые вычисления внутри функции, но сделать это единожды. Например, есть некий код:
var showAlert = function() {
alert("You shall not pass!");
};
setTimeout(showAlert, 3000);
Этот код с задержкой в 3 секунды вызывает функцию showAlert, которая, в свою очередь, выводит alert на экран. В случае, когда функция showAlert вызывается только здесь и больше не используется, мы можем воспользоваться анонимной функцией:
setTimeout(function() {
alert("You shall not pass!");
}, 3000);
Чаще всего анонимные функции используются в асинхронных функциях в качестве функций-коллбэков.
При запуске функции выделяется память под локальные переменные этой функции, а после запуска эти переменные удаляются из памяти. Таким образом, при каждом очередном запуске функции переменные принимают одно и то же значение.
function myCounter() {
var i = 0; // создается заново с каждым запуском
i++;
alert('i = ' + i);
}
myCounter(); // "i = 1"
myCounter(); // "i = 1"
myCounter(); // "i = 1"
Но если функция вернет в return другую функцию, которая будет как-либо использовать локальную перменную, то такая переменная останется в памяти. В таком случае говорят, что переменная "попала в замыкание".
function createCounter() {
var i = 0;
return function() {
i++; // остается в памяти, т.к. "кому-то" нужна
alert('i = ' + i);
}
}
var myCounter = createCounter();
myCounter(); // "i = 1"
myCounter(); // "i = 2"
myCounter(); // "i = 3"