Функции

Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.

*DRY – Don't Repeat Yourself (Не повторяй себя)*

Пример объявления функции:

function имя_функции(параметры, через, запятую) {
код функции
}
имя_функции(1)
function showMessage() {
alert( 'Привет всем присутствующим!' );
}

Возвращаемое значение

Мы можем воспринимать функцию как некоторую фабрику которая что-то получает и выдает какой-то результат своей работы.

Чтобы вернуть результат из функции используется оператор return.

function nameOfFunction(argument1, argument2) {
var result = 100;
return result; // таким образом, функция вернет значение переменной result
}

Важно заметить, что вернуть результат из функции вы можете только один раз.

function foo() {
return "a";
return "b"; // Этот return не имеет смысла потому как мы выйдем из функции еще на предыдущей строчке
}
## Вызов функции
Теперь мы знаем как создать(объявить) функцию, осталось разобраться с ee вызовом(запуском).
```jsx
// Делается это так
имя_функции() // <- в круглых скобках передаем значения в функцию через запятую
function sum(a, b){
return a + b
}
sum(1, 2) // функция вернет сумму двух чисел

Вызов функции является выражением, Т.е имеет значение... это значение можно присвоить в переменную

var foo = sum(5, 6); // вызов функции вернет нам сумму двух чисел
console.log(foo); // выведет в консоль число 11

Всплытие функций (hoisting)

Более детально мы будем обсуждать функции потом, справка будет расширена. Но пока можно обратить внимание на этот пример:

baz(); //здесь функция уже будет доступна и ошибки не произойдет, хотя мы можем подумать, что интерпретатор создаст ее только на следующих строчках
function baz() {
return 1;
}

Следует быть аккуратными с подобными эффектами, многие считают такое поведение опасным, поэтому следует сначала объявить функцию, а потом только вызывать ее.

Рекурсия

С рекурсией все просто... это возможность из функции foo вызывать саму себя функцию foo.

Напишем рекурсивную функцию, которая будет выводить в консоль числа от 0 до 100:

*Стоит заметить, что этот пример сложнее чем использование циклов, сделан от только для примера*

function foo(current, destination) {
console.log(current);
// Обратите внимание на префиксный инкремент
if (current < destination) foo(++current, destination);
}
foo(0, 100);

JS Bin

Живой пример

Рекурсия / Введение в программирование, урок 8 (JavaScript ES6)

Объявление Function Expression

Существует альтернативный синтаксис для объявления функции, который ещё более наглядно показывает, что функция – это всего лишь разновидность значения переменной.

Мы в переменную foo присваиваем функцию... в дальнейшем мы поймем, что это приводит нас к тому, что функции в JS это элементы первого порядка.

Анонимная функция – функция у которой нет собственного имени, в примере ниже, вы можете сказать, что функция имеет имя foo. Но это не совсем так, в переменной лежит анонимная функция.

var foo = function () {
console.log("foo");
};

*Смотря на пример выше мы должны вспомнить про всплытие переменных и функций*

foo(); //Выведет в консоль 'foo'
function foo() {
console.log("foo");
}
foo(); // Здесь мы получим ошибку. Почему?
var foo = function () {
console.log("foo");
};

Самовызывающиеся функции

Мы с вами уже увидели, что объявление функции может являться выражением. Выражения можно заключать в круглые скобки (Пример: (10 + 3) * 2). Давайте сделаем так: (function (){...})(). Что за ужас мы сделали? Мы объявили функцию в круглых скобках, потом из круглых скобок мы ее получили и вызвали. Т.к функции имеют свою область видимости переменных таким образом мы можем изолировать какие-то переменные в нашем модуле.

// Представим, что мы пишем модуль, и не хотим, чтобы его переменные конфликтовали с чужим кодом. Справиться с этой задачей можно таким образом:
(function () {
var $ = "foo";
// ... наш код
})();
console.log($); // Переменная $ будет отсутствовать

Callback function и передача функции как аргумент

Выше уже говорилось о том, что функции являются элементами первого класса, в первую очередь это обозначает, что функции можно передавать как аргументы в другие функции или методы. Результатом работы одной функции может быть другая функция.

var names = ["Demetrius", "Mariana", "Mathilde", "Gregor", "Daylen", "Shaun"]
var filter_function(name){
return name.length <= 6;
}
var f_name = names.filter(filter_function);

Замыкания

Замыкания многих пугают в этом языке... хотя они существуют и в других языках тоже. Замыкание – это возможность запоминать контекст при котором была создана функция. После создания функция имеет доступ к переменным которые были доступны на момент создания.

var a = 1;
function make_foo() {
var a = 2;
// создаем и возвращаем функцию. Функция которую мы вернем будет иметь доступ к переменно a в дальнейшем и переопределить это будет невозможно
return function () {
console.log(a);
};
}
var foo = make_foo();
foo(); // Выведет 2 в консоль

Для наглядность давайте еще попробуем написать функцию-счетчик

function makeCounter(initial_count) {
var count = initial_count || 0;
return function () {
count++;
console.log(count);
};
}
var c = makeCounter();
c(); // 1
c(); // 2

Псевдомассив аргументов "arguments"

warning

TODO: Дописать

JS Bin

Живой пример с счетчиком

За более детальной справкой обращаемся к этим страницам

Функции