call, apply и bind — в чём разница?
Три способа вручную задать контекст функции — и когда какой нужен.
callиapplyвызывают функцию с заданнымthisсразу.bindвозвращает новую функцию с привязаннымthis, не вызывая её.
call: аргументы через запятую
function greet(greeting) {
return greeting + ", " + this.name;
}
const user = { name: "Аня" };
console.log(greet.call(user, "Привет"));
Вывод:
Привет, Аня
apply: аргументы массивом
apply делает то же, что call, но аргументы передаются массивом. Запомнить помогает «apply — array».
function sum(a, b, c) {
return a + b + c + " от " + this.name;
}
const ctx = { name: "калькулятор" };
console.log(sum.apply(ctx, [1, 2, 3]));
Вывод:
6 от калькулятор
bind: новая функция на потом
bind не вызывает функцию, а возвращает её копию с навсегда привязанным this. Удобно для коллбэков, где контекст иначе потеряется.
const obj = {
name: "Сервис",
getName() { return this.name; },
};
const detached = obj.getName;
const bound = obj.getName.bind(obj); // зафиксировали this
console.log(bound());
console.log([0].map(bound)[0]); // даже как коллбэк помнит obj
Вывод:
Сервис Сервис
Сравнение
| Метод | Вызывает сразу? | Аргументы |
call | да | через запятую |
apply | да | массивом |
bind | нет, возвращает функцию | через запятую |
Практический приём: заимствование метода
Через call можно «одолжить» метод одного объекта для другого. Классика — превратить «похожий на массив» объект в массив.
function listArgs() {
// arguments — массивоподобный, но не массив
const real = Array.prototype.slice.call(arguments);
return real.map((x) => x * 2);
}
console.log(listArgs(1, 2, 3));
Вывод:
[ 2, 4, 6 ]
Итог
callиapplyвызывают функцию сразу; разница лишь в форме аргументов.bindвозвращает новую функцию с зафиксированнымthis— для коллбэков.- Через
callудобно «заимствовать» методы у других объектов.
Проверьте себя
1. Чем bind отличается от call и apply?
Abind вызывает функцию сразу
Bbind возвращает новую функцию с привязанным this, не вызывая её
Cbind работает только с массивами
DМежду ними нет разницы
2. Как передаются аргументы в apply?
AЧерез запятую
BМассивом
CТолько один аргумент
DЧерез объект
3. Зачем чаще всего применяют bind?
AЧтобы ускорить функцию
BЧтобы зафиксировать this для коллбэка, где контекст иначе теряется
CЧтобы превратить функцию в строку
DЧтобы удалить аргументы