← Назад к вопросам

Какие знаешь особенности function expression?

2.2 Middle🔥 111 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Особенности 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 DeclarationFunction Expression
HoistingПолностью поднимаетсяНе поднимается (только переменная)
ИмяОбязательноОпционально
ПрисваиваниеНетДа, переменной
Вызов до определенияДаНет
ЗамыканияДаДа, более часто используется

Когда использовать Function Expression

  • Когда нужно передать функцию как параметр
  • Для создания замыканий и приватного состояния
  • Для IIFE и модульных паттернов
  • Когда нужна стрелочная функция
  • Когда логически функция — это значение, а не инструкция