Объявление функций
Объявление функций
Function Declaration
Классическое объявление функции через ключевое слово function:
function greet(name) {
return `Привет, ${name}!`;
}
console.log(greet('Иван')); // 'Привет, Иван!'
Особенность: Function Declaration поднимается (hoisting) — функцию можно вызвать до её объявления в коде:
sayHello(); // 'Привет!' — работает до объявления!
function sayHello() {
console.log('Привет!');
}
Function Expression
Функция, присвоенная переменной:
const greet = function(name) {
return `Привет, ${name}!`;
};
// Именованное выражение функции (NFE)
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1); // fact доступна внутри
};
Отличие от Declaration: Function Expression НЕ поднимается. Обращение до присваивания — ReferenceError (для const/let) или TypeError (для var):
greet(); // TypeError: greet is not a function
var greet = function() { console.log('hi'); };
hello(); // ReferenceError: Cannot access 'hello' before initialization
const hello = function() { console.log('hello'); };
Анонимные и именованные функции
// Анонимная функция (нет имени)
const sum = function(a, b) { return a + b; };
sum.name; // 'sum' — V8 выводит имя из переменной
// Именованная функция-выражение
const sum2 = function mySum(a, b) { return a + b; };
sum2.name; // 'mySum'
// В stack trace именованные функции отображаются лучше
Для коллбеков используйте именованные функции — так stack trace при ошибке будет более информативным.
Функции как значения первого класса
В JavaScript функция — это объект. Её можно передавать, хранить в массиве, возвращать:
// Функция как аргумент
[1, 2, 3].map(function double(x) { return x * 2; });
// Функция как возвращаемое значение
function makeMultiplier(n) {
return function(x) { return x * n; }; // замыкание!
}
const triple = makeMultiplier(3);
triple(5); // 15
При Function Declaration движок V8 на этапе парсинга “поднимает” (hoist) всю функцию в память. Поэтому вызов до объявления работает.
При Function Expression поднимается только объявление переменной (для var — как undefined), но не присваивание. Поэтому:
var fn = function(){}— до присваиванияfn === undefinedlet/const fn = function(){}— до присваивания TDZ