JavaScript функции: от объявления до сложных конструкций
Основы функций в JavaScript
Функция в JavaScript - это блок кода, предназначенный для выполнения определённой задачи. Функции являются объектами первого класса, их можно присваивать, передавать и возвращать. Рассмотрим основной способ создания функций.
Как объявить функцию, которая будет доступна до её определения?
Function Declaration (объявление функции) - наиболее часто используемый способ.
function showMessage(text) {
return 'Сообщение: ' + text;
}
console.log(showMessage('Привет')); // Сообщение: Привет
Js function (функция javascript)
Такие функции поднимаются (hoisting) в начало своей области видимости, поэтому вызов может находиться до строки объявления.
console.log(multiply(2, 3)); // 6
function multiply(a, b) {
return a * b;
}
Возможные проблемы:
- Повторное объявление функции с одинаковым именем приводит к перезаписи.
- Внутри блоков (if, for) Function Declaration может вести себя неожиданно (strict mode для блоков).
Как создать функцию, которая не поднимается и хранится как переменная?
Function Expression присваивает функцию переменной.
const greeting = function(name) {
return 'Здравствуйте, ' + name + '!';
};
console.log(greeting('Мария'));
Такую функцию нельзя вызвать до присваивания.
Типичные ошибки:
- ReferenceError при попытке вызова до определения.
- Отсутствие точки с запятой после присваивания может нарушить цепочку вызовов.
Цели использования:
- Условное определение функции (в зависимости от флага).
- Колбэки и обработчики событий.
- Создание анонимных функций.
Как написать компактную функцию без собственного контекста this?
Стрелочные функции (Arrow Functions) имеют лаконичный синтаксис и не создают собственный this.
const add = (a, b) => a + b;
console.log(add(5, 3)); // 8
Если тело состоит из нескольких выражений, нужно обернуть в фигурные скобки и использовать return.
const sumAndLog = (x, y) => {
const result = x + y;
console.log('Результат:', result);
return result;
};
sumAndLog(4, 6);
Проблемы:
- Нет доступа к псевдомассиву arguments.
- Нельзя использовать как конструктор (новый объект).
- this берётся из внешней области, что может быть неожиданностью.
Как выполнить функцию сразу после её создания, изолируя переменные?
Немедленно вызываемая функция (IIFE) выполняется один раз.
(function() {
var localVar = 'Это видно только внутри';
console.log(localVar);
})();
// localVar не доступна снаружи
Часто используется для создания модулей.
Распространённые ошибки:
- Пропуск точки с запятой перед IIFE может вызвать конфликт с предыдущим выражением.
- Забытое круглые скобки для вызова.
Как добавить функцию в качестве метода объекта?
Метод - это функция, присвоенная свойству объекта.
const user = {
name: 'Алексей',
greet() {
return 'Привет, ' + this.name;
}
};
console.log(user.greet()); // Привет, Алексей
Значение this определяется тем, как вызывается метод.
Ошибки:
- Потеря контекста при передаче метода как колбэка.
- Использование стрелочной функции в методе объекта (this не будет ссылаться на объект).
Как создать объекты с помощью функции-конструктора?
Функции-конструкторы вызываются с new.
function Person(name, age) {
this.name = name;
this.age = age;
}
const alice = new Person('Алиса', 25);
console.log(alice.name); // Алиса
Обычно используют классы, но конструкторы все ещё актуальны.
Частые проблемы:
- Забытый new - функция вернёт undefined и присвоит свойства глобальному объекту.
- Прототипное наследование требует дополнительных усилий.
Расширенные примеры работы с функциями
Замыкание (Closure)
Функция, которая запоминает переменные из внешней области даже после завершения внешней функции.
function createMultiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = createMultiplier(2);
console.log(double(5)); // 10
const triple = createMultiplier(3);
console.log(triple(5)); // 15
10 15
Замыкания широко применяются для создания функций с сохранённым состоянием (счётчики, мемоизация).
Рекурсия
Функция вызывает саму себя. Пример вычисления факториала.
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
120
Рекурсия удобна для обхода деревьев, графов, математических вычислений, но может привести к переполнению стека при глубоких вызовах.
Колбэки и асинхронные операции
Функция, передаваемая как аргумент другой функции, выполняется после завершения операции.
function processData(data, callback) {
const result = data.toUpperCase();
callback(result);
}
processData('hello', function(output) {
console.log(output); // HELLO
});
HELLO
Колбэки были основой асинхронного программирования до появления промисов и async/await.
Методы call, apply, bind для управления this
Позволяют явно задать контекст вызова функции.
function showFullName() {
return this.firstName + ' ' + this.lastName;
}
const person = { firstName: 'Иван', lastName: 'Петров' };
console.log(showFullName.call(person)); // Иван Петров
console.log(showFullName.apply(person)); // Иван Петров
const bound = showFullName.bind(person);
console.log(bound()); // Иван Петров
Иван Петров Иван Петров Иван Петров
call и apply отличаются способом передачи аргументов: call через запятую, apply через массив.