Какие знаешь особенности function expression?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Особенности Function Expression
Function Expression — это способ определения функции через присваивание функции переменной. Это отличается от Function Declaration и имеет ряд важных особенностей, которые нужно понимать при разработке.
1. Отсутствие hoisting
Одно из ключевых отличий function expression от function declaration — она не поднимается (hoisting) на верхнюю часть области видимости. Переменная поднимается, но инициализируется как undefined:
// ❌ Ошибка: ReferenceError
console.log(add(2, 3)); // add is not a function
const add = function(a, b) {
return a + b;
};
// ✅ Function declaration работает
console.log(sum(2, 3)); // 5
function sum(a, b) {
return a + b;
}
2. Может быть анонимной или именованной
Function expression может быть как без имени (анонимная), так и с именем (именованная). Имя доступно только внутри функции:
// Анонимная function expression
const greet = function(name) {
return `Hello, ${name}`;
};
// Именованная function expression
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1); // Может рекурсивно вызвать себя
};
// Вне функции имя fact не доступно
console.log(typeof fact); // undefined
console.log(typeof factorial); // function
3. Присваивается переменной как значение
Function expression — это просто значение, которое присваивается переменной. Это позволяет передавать функции как аргументы и возвращать их как результат:
// Функция как параметр
function executeCallback(callback, value) {
return callback(value);
}
const double = function(x) {
return x * 2;
};
console.log(executeCallback(double, 5)); // 10
// Функция как возвращаемое значение
function createMultiplier(factor) {
return function(x) {
return x * factor;
};
}
const triple = createMultiplier(3);
console.log(triple(4)); // 12
4. Область видимости и замыкания
Function expression создаёт замыкание, захватывая переменные из лексической области видимости. Это позволяет реализовать приватные переменные и состояние:
function createCounter() {
let count = 0; // Приватная переменная
return {
increment: function() {
return ++count;
},
decrement: function() {
return --count;
},
getCount: function() {
return count;
}
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1
console.log(counter.count); // undefined — приватная!
5. Особенности с this
Одно из важных отличий — обычная function expression не связана с объектом автоматически. Значение this зависит от способа вызова:
// Обычная function expression
const obj = {
name: "Object",
greet: function() {
console.log(`Hello, I am ${this.name}`);
}
};
obj.greet(); // "Hello, I am Object" — this = obj
const greet = obj.greet;
greet(); // "Hello, I am undefined" — this = undefined (strict mode) или window
// Стрелочная функция привязана к this автоматически
const obj2 = {
name: "Object",
greet: () => {
console.log(`Hello, I am ${this.name}`); // this = глобальный контекст
}
};
6. Используется в паттернах IIFE и IIFE и модули
Function expression часто используется для создания IIFE (Immediately Invoked Function Expression) для создания приватных областей видимости:
// IIFE
(function() {
const private = "This is private";
console.log(private);
})();
console.log(typeof private); // undefined
// Модульный паттерн
const module = (function() {
const privateVar = 10;
return {
getPrivate: function() {
return privateVar;
},
setPrivate: function(value) {
privateVar = value;
}
};
})();
console.log(module.getPrivate()); // 10
7. Callback и асинхронные операции
Function expression особенно удобна для использования в качестве колбэков в асинхронных операциях:
const data = [1, 2, 3, 4, 5];
// Как колбэк в методах массива
const doubled = data.map(function(x) {
return x * 2;
});
const filtered = data.filter(function(x) {
return x > 2;
});
// Обработка обещаний
fetch(/api/data)
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log(data);
});
8. Различие между const и let в function expression
Обычно function expression объявляют с const для предотвращения переприсваивания, но это влияет на переассигнацию, а не на hoisting:
// const — функцию нельзя переприсвоить
const fn1 = function() {};
fn1 = function() {}; // TypeError
// let — функцию можно переприсвоить
let fn2 = function() {};
fn2 = function() {}; // OK, но не рекомендуется
Сравнение с Function Declaration
| Особенность | Function Declaration | Function Expression |
|---|---|---|
| Hoisting | Полностью поднимается | Не поднимается (только переменная) |
| Имя | Обязательно | Опционально |
| Присваивание | Нет | Да, переменной |
| Вызов до определения | Да | Нет |
| Замыкания | Да | Да, более часто используется |
Когда использовать Function Expression
- Когда нужно передать функцию как параметр
- Для создания замыканий и приватного состояния
- Для IIFE и модульных паттернов
- Когда нужна стрелочная функция
- Когда логически функция — это значение, а не инструкция