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

Как передается функция?

1.2 Junior🔥 241 комментариев
#JavaScript Core

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

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

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

Как передается функция в JavaScript

Функции в JavaScript - это объекты первого класса (first-class objects). Их можно передавать как параметры, возвращать из функций, сохранять в переменные. Это один из самых мощных механизмов языка.

1. Передача функции как параметра

Когда вы передаете функцию в другую функцию, передается ссылка на функцию (не копия, а ССЫЛКА):

// Передача функции как callback
function greet(name) {
  return 'Hello, ' + name;
}

// executeCallback ПОЛУЧАЕТ ССЫЛКУ на функцию greet
function executeCallback(func, name) {
  // Вызываем переданную функцию
  return func(name);
}

// greet передается БЕЗ скобок (скобки вызывают функцию)
const result = executeCallback(greet, 'Alice');
console.log(result); // 'Hello, Alice'

// НЕПРАВИЛЬНО - вызовет функцию сразу
const wrong = executeCallback(greet('Alice')); // Ошибка!

2. Анонимные функции

Вы можете передать функцию без имени:

// Вместо именованной функции используйте анонимную
const result = executeCallback(function(name) {
  return 'Hi, ' + name;
}, 'Bob');

// Или стрелочную функцию (современный способ)
const result2 = executeCallback((name) => {
  return 'Hi, ' + name;
}, 'Charlie');

// Еще короче
const result3 = executeCallback(name => 'Hi, ' + name, 'David');

3. Callback функции в реальной жизни

Это часто используется для обработки событий и асинхронных операций:

// Обработка события
button.addEventListener('click', () => {
  console.log('Button clicked!');
});

// Фильтрация массива с функцией
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

// Преобразование массива
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Сумма всех элементов
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

// fetch с callback (промисы)
fetch('/api/users')
  .then(response => response.json()) // Передаем функцию
  .then(data => console.log(data))   // Еще функция
  .catch(error => console.error(error)); // И еще

4. Замыкание (Closure)

Когда функция передается, она сохраняет доступ к переменным из своей области видимости:

function createCounter(start = 0) {
  let count = start;

  // Возвращаем ФУНКЦИЮ, которая имеет доступ к count
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter(10);
console.log(counter()); // 11
console.log(counter()); // 12
console.log(counter()); // 13

// Каждый counter имеет свой count
const anotherCounter = createCounter(100);
console.log(anotherCounter()); // 101
console.log(counter()); // 14 (первый счетчик не изменился)

5. Передача функции с контекстом (this)

Это часто вызывает ошибки, особенно в обработчиках событий:

class Player {
  constructor(name) {
    this.name = name;
    this.score = 0;
  }

  addScore(points) {
    this.score += points;
    console.log(this.name + ' has ' + this.score + ' points');
  }
}

const player = new Player('Alice');

// НЕПРАВИЛЬНО - this станет undefined
button.addEventListener('click', player.addScore);
button.click(); // Ошибка: Cannot read property 'name' of undefined

// ПРАВИЛЬНО 1 - используйте стрелочную функцию
button.addEventListener('click', () => player.addScore(10));

// ПРАВИЛЬНО 2 - используйте bind
button.addEventListener('click', player.addScore.bind(player, 10));

// ПРАВИЛЬНО 3 - оборните в функцию
button.addEventListener('click', function() {
  player.addScore(10);
});

6. Higher-Order Functions (HOF)

Функция, которая принимает или возвращает другую функцию:

// HOF - возвращает функцию
function makeMultiplier(factor) {
  return (number) => number * factor;
}

const double = makeMultiplier(2);
const triple = makeMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

// HOF - принимает функцию
function applyTwice(func, value) {
  return func(func(value));
}

const add5 = (x) => x + 5;
console.log(applyTwice(add5, 10)); // 20 (10 + 5 + 5)

// Композиция функций
function compose(f, g) {
  return (x) => f(g(x));
}

const addOne = (x) => x + 1;
const double2 = (x) => x * 2;
const addThenDouble = compose(double2, addOne);

console.log(addThenDouble(5)); // 12 ((5 + 1) * 2)

7. В React - функции как props

В React часто передаются функции как props:

// Дочерний компонент получает функцию
function Button({ onClick, children }) {
  return (
    <button onClick={onClick}>
      {children}
    </button>
  );
}

// Родительский компонент передает функцию
function Parent() {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return (
    <Button onClick={handleClick}>
      Click me
    </Button>
  );
}

// С параметрами
function List({ items }) {
  const handleDelete = (id) => {
    console.log('Delete item ' + id);
  };

  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {item.name}
          <button onClick={() => handleDelete(item.id)}>Delete</button>
        </li>
      ))}
    </ul>
  );
}

8. Копирование функции

Осторожно - функции передаются по ссылке, не копируются:

function original() {
  return 'original';
}

const copy = original; // Это ссылка, не копия

// Обе переменные указывают на одну функцию
console.log(original === copy); // true

// Если вам ДЕЙСТВИТЕЛЬНО нужна копия:
const trueCopy = original.bind({}); // Новая функция с другим this

// Но обычно в копировании нет необходимости

Ключевые моменты

  1. Функции передаются ПО ССЫЛКЕ, не по значению
  2. При передаче БЕЗ скобок - передается сама функция
  3. С скобками () - вызывается функция и передается ее результат
  4. Замыкания сохраняют доступ к переменным
  5. this может измениться - используйте стрелочные функции или bind
  6. Это основа для callbacks, обработчиков событий и асинхронного кода

Овладение этим механизмом критично для фронтенд-разработки!