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() не вызывает функцию сразу, а подготавливает её к будущему вызову, поэтому особенно полезен для колбэков, методов объектов и частичного применения аргументов.