Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает bind для функций в JavaScript
bind() — метод, который создаёт новую функцию с привязанным контекстом (this) и опционально зафиксированными аргументами. Это отличается от call() и apply(), которые вызывают функцию сразу.
Основной синтаксис
// bind() создаёт НОВУЮ функцию, но не вызывает её
const boundFunction = originalFunction.bind(thisArg, arg1, arg2, ...);
// Затем ты можешь вызвать её когда угодно
boundFunction(arg3, arg4);
Проблема: контекст this
Без bind() контекст this может быть потерян:
const person = {
name: 'Иван',
greet() {
console.log(`Привет, ${this.name}`);
}
};
// ❌ Потеря контекста
const greet = person.greet;
greet(); // Error: this.name undefined (this = window/global)
// ✅ С bind()
const boundGreet = person.greet.bind(person);
boundGreet(); // "Привет, Иван"
Привязка контекста (this)
const user = {
id: 1,
name: 'Alice',
getId() {
return this.id;
}
};
// bind() создаёт функцию с фиксированным this
const getUserId = user.getId.bind(user);
console.log(getUserId()); // 1
// Можешь привязать к другому объекту
const admin = { id: 999 };
const getAdminId = user.getId.bind(admin);
console.log(getAdminId()); // 999
Partial Application (Частичное применение аргументов)
function multiply(a, b, c) {
return a * b * c;
}
// Зафиксируй первые аргументы
const multiplyBy2And3 = multiply.bind(null, 2, 3);
console.log(multiplyBy2And3(4)); // 2 * 3 * 4 = 24
// Полезно для callback'ов
const double = multiply.bind(null, 2, 1);
console.log(double(5)); // 2 * 1 * 5 = 10
Практические примеры в Node.js Backend
1. Сохранение контекста в callback'ах
class UserService {
private db: Database;
constructor(db: Database) {
this.db = db;
}
async fetchUser(id: string) {
return this.db.query('SELECT * FROM users WHERE id = ?', [id]);
}
async process(ids: string[]) {
// ❌ Потеря this
// ids.forEach(function(id) {
// this.fetchUser(id); // this === undefined
// });
// ✅ С bind()
ids.forEach(this.fetchUser.bind(this));
// ✅ Или используй стрелочные функции
ids.forEach(id => this.fetchUser(id));
}
}
2. Event listeners
class EventManager {
name: string = 'Manager';
onEvent(event: Event) {
console.log(`${this.name} received:`, event);
}
setup(target: EventTarget) {
// ❌ Потеря this
// target.addEventListener('click', this.onEvent);
// ✅ С bind()
target.addEventListener('click', this.onEvent.bind(this));
}
}
const manager = new EventManager();
manager.setup(button);
3. SetTimeout и setInterval
class Timer {
interval: number = 1000;
logTime() {
console.log(new Date().toISOString());
}
start() {
// ❌ Потеря this
// setInterval(this.logTime, this.interval);
// ✅ С bind()
setInterval(this.logTime.bind(this), this.interval);
}
}
const timer = new Timer();
timer.start();
4. Создание функций-обработчиков с аргументами
class DataProcessor {
async processItem(id: string, options: any) {
const data = await this.fetch(id);
return { ...data, ...options };
}
async processMany(ids: string[], options: any) {
// Создаём функцию с зафиксированным options
const processor = this.processItem.bind(this, undefined, options);
// Проблема: bind фиксирует аргументы слева
// Лучше использовать стрелочную функцию:
return Promise.all(
ids.map(id => this.processItem(id, options))
);
}
}
Сравнение: bind, call, apply
function introduce(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'Bob' };
// call() — вызывает сразу
introduce.call(person, 'Hello', '!'); // "Hello, Bob!"
// apply() — вызывает сразу, аргументы массивом
introduce.apply(person, ['Hi', '?']); // "Hi, Bob?"
// bind() — возвращает новую функцию
const greet = introduce.bind(person, 'Hey');
greet('...'); // "Hey, Bob..."
TypeScript: стрелочные функции vs bind()
// Стрелочные функции (предпочтительно)
class Service {
name = 'Service';
// this автоматически привязан в стрелочной функции
handleClick = () => {
console.log(this.name);
};
}
// vs bind() в конструкторе
class OldService {
name = 'OldService';
constructor() {
// Нужно явно привязывать
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log(this.name);
};
}
Ключевые моменты
bind()не вызывает функцию, возвращает новую- Контекст
thisзафиксирован и не может быть изменён - Частичное применение аргументов работает (currying)
- В TypeScript и современном JS предпочитай стрелочные функции
bind()всё ещё нужен для интеграции с legacy кодом