Learn JavaScript

bind() - метод для привязки this и аргументов в JavaScript

bind() - это метод функций, который создаёт новую функцию с привязанным this и, при необходимости, с заранее переданными аргументами.

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

Синтаксис

Базовая запись выглядит так:

const newFunction = fn.bind(thisArg, arg1, arg2);

Где:

  • thisArg - значение, которое станет this внутри новой функции
  • arg1, arg2 и дальше - необязательные аргументы, которые будут подставлены заранее

Что делает bind()

bind() не вызывает функцию сразу.

Он возвращает новую функцию.

function greet() {
  console.log("Привет");
}

const boundGreet = greet.bind(null);

console.log(typeof boundGreet); // "function"

То есть после bind() у нас появляется новая функция, которую уже можно вызвать позже.

Привязка this

Самый частый сценарий - зафиксировать this.

const user = {
  name: "Анна",
  showName() {
    console.log(this.name);
  },
};

const show = user.showName.bind(user);

show(); // "Анна"

Без bind() здесь часто возникает проблема: если вытащить метод из объекта и вызвать отдельно, this потеряется.

const user = {
  name: "Анна",
  showName() {
    console.log(this.name);
  },
};

const show = user.showName;

// show(); // this уже не указывает на user

bind(user) решает именно эту задачу.

Почему это часто нужно

Метод объекта нередко передают как колбэк.

Например:

const user = {
  name: "Анна",
  showName() {
    console.log(this.name);
  },
};

setTimeout(user.showName.bind(user), 100);

Здесь bind() гарантирует, что внутри showName this останется ссылкой на user.

bind() и аргументы заранее

bind() умеет не только фиксировать this, но и заранее подставлять аргументы.

function greet(prefix, suffix) {
  return `${prefix}Анна${suffix}`;
}

const sayHi = greet.bind(null, "Привет, ");

console.log(sayHi("!")); // "Привет, Анна!"

В этом примере:

  • "Привет, " уже привязан как первый аргумент
  • "!" передаётся позже при вызове

Такой приём называют частичным применением аргументов.

Пример с this и аргументами вместе

Обычно это выглядит так:

const user = {
  name: "Анна",
};

function greet(prefix, suffix) {
  return `${prefix}${this.name}${suffix}`;
}

const sayHi = greet.bind(user, "Привет, ");

console.log(sayHi("!")); // "Привет, Анна!"

Здесь bind() сразу делает две вещи:

  • фиксирует this
  • подставляет первый аргумент

bind() отличается от call() и apply()

Эти методы часто путают, потому что все они работают с this.

Главное различие такое:

  • bind() возвращает новую функцию
  • call() вызывает функцию сразу
  • apply() тоже вызывает функцию сразу

Пример:

function greet() {
  console.log(this.name);
}

const user = { name: "Анна" };

const bound = greet.bind(user);

bound();           // "Анна"
greet.call(user);  // "Анна"
greet.apply(user); // "Анна"

Если функцию нужно выполнить немедленно, чаще используют call() или apply().

Если функцию нужно подготовить сейчас, а вызвать позже, нужен bind().

bind() всегда возвращает новую функцию

Это тоже важный момент.

function greet() {}

const bound = greet.bind(null);

console.log(bound === greet); // false

Исходная функция не меняется. bind() создаёт отдельную новую функцию.

Повторный bind не меняет уже привязанный this

Если функция уже была привязана, повторный bind() не заменит первый this.

function show() {
  console.log(this.name);
}

const first = show.bind({ name: "Анна" });
const second = first.bind({ name: "Игорь" });

second(); // "Анна"

То есть первый bind() уже зафиксировал this.

При этом дополнительные заранее переданные аргументы всё ещё могут накапливаться.

bind() и стрелочные функции

У стрелочных функций нет собственного this, поэтому bind() не даёт для них тот же эффект, что для обычных функций.

const arrow = () => {
  console.log(this);
};

const bound = arrow.bind({ name: "Анна" });

bound();

Синтаксически это работает, но this стрелочной функции не становится объектом из bind().

Поэтому bind() обычно используют именно с обычными функциями и методами.

bind() можно применять только к функции

Так как это метод функций, на обычных значениях он не работает.

const user = {};

// user.bind(null); // TypeError

Сначала должно быть именно вызываемое значение, то есть функция.

bind() и конструкторы

Есть ещё один важный нюанс: результат bind() можно использовать с new, если исходная функция была обычной функцией-конструктором.

function User(name) {
  this.name = name;
}

const BoundUser = User.bind(null, "Анна");
const user = new BoundUser();

console.log(user.name); // "Анна"

В таком случае заранее переданные аргументы сохраняются.

Но this, переданный в bind(), при вызове через new уже не играет той же роли, потому что создаётся новый объект.

Для базового понимания достаточно помнить: с обычным вызовом bind() фиксирует this, а с new поведение отличается.

Когда это полезно

bind() особенно удобен, когда:

  • метод объекта передают как колбэк
  • функцию нужно вызвать позже, но с уже зафиксированным this
  • часть аргументов известна заранее
  • нужно аккуратно подготовить обработчик или функцию-обёртку

Пример:

const logger = {
  prefix: "[LOG]",
  print(message) {
    console.log(this.prefix, message);
  },
};

const log = logger.print.bind(logger);

log("JavaScript"); // "[LOG] JavaScript"

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

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

function greet() {
  console.log("Привет");
}

const result = greet.bind(null);

Здесь функция ещё не выполнена. result - это новая функция.

Чтобы выполнить её, нужен отдельный вызов:

result();

Забывать вызвать результат bind()

const user = {
  name: "Анна",
  showName() {
    console.log(this.name);
  },
};

user.showName.bind(user); // ничего не выведет

bind() только создаёт функцию, но не запускает её.

Пытаться использовать bind() не на функции

const user = {};

// user.bind(null); // TypeError

bind() есть у функций, а не у любых объектов.

Ожидать, что bind() изменит исходную функцию

function show() {
  console.log(this.name);
}

const bound = show.bind({ name: "Анна" });

Исходная show осталась прежней. Привязка находится у новой функции bound.

Думать, что bind() нормально “чинит” this у стрелочной функции

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

Быстрая памятка

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

Коротко

bind() в JavaScript нужен, чтобы создать новую функцию с привязанным this и, при необходимости, с заранее заданными аргументами. Главное, что стоит запомнить: bind() не вызывает функцию сразу, а подготавливает её к будущему вызову, поэтому особенно полезен для колбэков, методов объектов и частичного применения аргументов.