Gernar
Frontend DeveloperJavaScript

Интервью-вопрос

Что делает метод bind

bind нужен, чтобы получить новую функцию с заранее заданным this и частично примененными аргументами. Главный риск в ответе - перепутать bind с call/apply или забыть, что стрелочные функции не меняют this через bind.

Добавлен
Редакция

Подготовьте короткий ответ и пару деталей на случай уточняющих вопросов.

🐰0
🥚0

Мини-квиз

Проверка перед разбором

Несколько быстрых вопросов перед разбором. Так проще поймать места, которые только кажутся понятными.

Вопрос 1 из 50 правильно

Что лучше ответить про базовое поведение bind?

Вы хотите коротко объяснить метод на интервью.

Варианты ответа

Разбор

Разобраться, а не зазубрить

Дальше разбираем суть, типичные уточнения и места, где легко сказать лишнее или перепутать термины.

Базовая идея

Function.prototype.bind возвращает новую функцию. Когда вы вызываете эту новую функцию, внутри исходной функции this будет тем значением, которое вы передали в bind первым аргументом.

function showName() {
  return this.name;
}

const user = { name: "Alice" };
const boundShowName = showName.bind(user);

console.log(boundShowName()); // "Alice"

Важно сказать именно так: возвращает новую функцию. Если вы скажете, что bind вызывает функцию, вас быстро проверят вопросом про отличие от call и apply.

Почему это важно для callbacks

В JavaScript значение this зависит от того, как функция вызвана. Если метод объекта передать как обычное значение, связь с объектом теряется.

const user = {
  name: "Alice",
  greet() {
    console.log(`Hello, ${this.name}`);
  },
};

// Плохо: метод передан как функция, контекст может потеряться.
setTimeout(user.greet, 1000);

// Безопаснее: создаем callback с фиксированным this.
setTimeout(user.greet.bind(user), 1000);

В UI такая ошибка часто выглядит не как ошибка this, а как неверный текст, не тот пользователь в сообщении, сломанный обработчик клика или падение в консоли после таймера. Практический вывод для frontend-кода простой. Если callback зависит от this, не передавайте метод сам по себе. Либо привяжите контекст через bind, либо передайте обертку вроде () => user.greet(), если так код читается лучше.

Как выбрать bind, call или apply

Как выбрать способ вызова

1Нужно вызвать функцию прямо сейчас с нужным this?
Используйте call или apply, не bind.
2Нужно передать метод как callback и сохранить объект в this?
Используйте bind или обертку, которая вызывает метод у нужного объекта.
3Нужно заранее зафиксировать часть аргументов?
bind подойдет, если this не важен, первым аргументом часто передают null.
4Функция стрелочная и проблема именно в this?
bind не поможет. Проверьте внешнюю область видимости или замените стрелку на обычную функцию там, где нужен динамический this.

call и apply нужны, когда функцию надо выполнить сейчас. bind нужен, когда функцию надо вызвать позже, например как обработчик события, callback таймера или функцию с заранее подготовленными аргументами.

function sum(a, b) {
  return a + b;
}

sum.call(null, 2, 3); // 5, вызов сразу
sum.apply(null, [2, 3]); // 5, вызов сразу

const addTwo = sum.bind(null, 2);
addTwo(3); // 5, вызов позже

Если на интервью вас просят сравнить эти методы, начните с времени вызова. Это самый короткий путь к правильному ответу.

Частичное применение аргументов

bind может фиксировать не только this, но и первые аргументы функции. Первый аргумент bind всегда относится к this, а все следующие становятся заранее переданными параметрами.

function multiply(a, b) {
  return a * b;
}

const double = multiply.bind(null, 2);

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

Здесь null означает, что this нам не нужен. Значение 2 становится первым аргументом a, а 5 передается позже как b. Типичная ошибка - написать multiply.bind(2) и думать, что 2 попал в a. На самом деле он попал бы в this.

Ловушка со стрелочными функциями

Стрелочные функции не имеют собственного this. Они берут this из внешней области видимости, поэтому bind, call и apply не могут поменять их контекст.

const obj = { name: "Alice" };

const arrow = () => this.name;
const boundArrow = arrow.bind(obj);

console.log(boundArrow()); // не "Alice"

Для интервью подойдет такая формулировка. bind можно вызвать у стрелочной функции, но он не изменит ее this. Если вам нужен управляемый this, используйте обычную функцию или поменяйте структуру кода.

Нюанс для React и обработчиков

В старых class components bind часто использовали для привязки методов к экземпляру компонента. Сейчас в функциональных компонентах чаще используют замыкания и хуки, но сам принцип остался важным: каждый вызов bind создает новую функцию.

// Плохо без причины: новая функция на каждом рендере.
<button onClick={this.handleClick.bind(this)}>Save</button>

// Лучше для class component: привязать один раз.
constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}

Это не значит, что bind всегда запрещен. Риск появляется, когда новая ссылка на функцию уходит в мемоизированные дочерние компоненты, обработчики создаются в больших списках или код становится сложнее читать. На интервью достаточно показать, что вы понимаете этот компромисс.

Cleanup для DOM-событий

Для браузерных событий важна та же ссылка на функцию. Если вызвать bind при добавлении и еще раз при снятии listener, получится две разные функции. Браузер не удалит старый обработчик.

// Плохо: removeEventListener получает другую функцию.
window.addEventListener("resize", this.onResize.bind(this));
window.removeEventListener("resize", this.onResize.bind(this));

// Безопаснее: сохранить ссылку.
this.boundOnResize = this.onResize.bind(this);
window.addEventListener("resize", this.boundOnResize);
window.removeEventListener("resize", this.boundOnResize);

Последствия для frontend-кода неприятные. Обработчик может сработать несколько раз, отправить лишний запрос, обновить уже удаленный UI или остаться в памяти после cleanup. Поэтому результат bind лучше хранить там, где вы сможете передать ту же ссылку в очистку.

Практический вывод

Хороший короткий ответ может звучать так:

Метод bind возвращает новую функцию с заранее привязанным this. Он не вызывает функцию сразу, поэтому отличается от call и apply. Дополнительно bind может зафиксировать часть аргументов. Я бы использовал его, когда нужно передать метод как callback и не потерять контекст, но помнил бы, что со стрелочными функциями this через bind не меняется.

Такой ответ закрывает главное: поведение, отличие от соседних методов, практическое применение и важную ловушку. Если хотите усилить ответ, добавьте пример с callback или частичным применением аргументов.

Частые ошибки

Где обычно ошибаются

Проверьте формулировки, которые звучат уверенно, но на интервью быстро выдают пробелы.

  1. 1

    Думать, что bind сразу вызывает функцию

    bind возвращает новую функцию. Если вы забыли вызвать результат или передать его как callback, код ничего не сделает. Со стороны это часто выглядит так, будто обработчик не сработал. Для немедленного вызова используйте call или apply.
  2. 2

    Пытаться перебиндить уже привязанную функцию

    После первого bind значение this уже зафиксировано. Повторный bind, call или apply не заменят его, поэтому такой код вводит в заблуждение и часто ломает ожидания в тестах.
  3. 3

    Использовать bind для стрелочной функции ради this

    Стрелочная функция не имеет собственного this. Она берет его из внешней области, поэтому bind не исправит потерянный контекст. Если нужен динамический this, используйте обычную функцию или измените место объявления.
  4. 4

    Создавать новые bound-функции на каждом рендере без причины

    Каждый вызов bind создает новый объект функции. В React это может передавать новые props в дочерний компонент и снижать пользу от React.memo. Безопаснее привязать обработчик один раз, использовать class fields или useCallback, если это действительно нужно.
  5. 5

    Снимать DOM-listener другой ссылкой

    element.addEventListener("click", handler.bind(this)) и element.removeEventListener("click", handler.bind(this)) используют разные функции. Обработчик останется висеть. В UI это дает двойные клики, лишние запросы и утечки после размонтирования. Сохраните результат bind в переменную или поле и снимайте именно эту ссылку.
  6. 6

    Не отличать контекст от аргументов

    Первый аргумент bind задает this, а следующие аргументы фиксируются как первые параметры функции. Если перепутать порядок, вы получите неверный id в обработчике или запросе. Например, UI может удалить не тот элемент или отправить лишний запрос, а ошибка проявится только в runtime.

Follow-up

Что могут спросить дальше

Короткие ответы на вопросы, которыми проверяют понимание this, callbacks и способов вызова функций.

Живые ответы

Видео с похожим вопросом

Если найдем публичные интервью с таким вопросом, добавим их сюда. Их удобно смотреть после теории, чтобы свериться с живыми ответами.

Пока видео нет. Когда появятся подходящие публичные интервью, добавим их в этот блок, чтобы можно было сравнить разбор с тем, как отвечают реальные кандидаты.

Содержание