call() - это метод функций, который сразу вызывает функцию с указанным this и списком аргументов.
Если говорить просто, call() нужен, когда функцию надо выполнить прямо сейчас, но с нужным контекстом.
Синтаксис
Базовая запись выглядит так:
fn.call(thisArg, arg1, arg2, arg3)
Где:
thisArg- значение, которое станетthisвнутри функцииarg1,arg2,arg3- аргументы функции
Что делает call()
call() сразу вызывает функцию.
Это главное отличие от bind(), который только создаёт новую функцию.
function greet() {
console.log("Привет");
}
greet.call(null); // "Привет"
Здесь функция выполняется сразу в момент вызова call().
Зачем передавать this через call()
Чаще всего call() используют, когда функция зависит от this.
function showName() {
console.log(this.name);
}
const user = { name: "Анна" };
showName.call(user); // "Анна"
Без call() эта функция не знает, к какому объекту должна относиться.
Пример с обычной функцией и разными объектами
Одна и та же функция может работать с разными объектами.
function showName() {
console.log(this.name);
}
const user1 = { name: "Анна" };
const user2 = { name: "Игорь" };
showName.call(user1); // "Анна"
showName.call(user2); // "Игорь"
Это удобно, когда логика одна и та же, а данные разные.
call() и аргументы
Через call() можно не только передать this, но и обычные аргументы функции.
function greet(prefix, suffix) {
console.log(`${prefix}${this.name}${suffix}`);
}
const user = { name: "Анна" };
greet.call(user, "Привет, ", "!"); // "Привет, Анна!"
Порядок тут такой:
- первым идёт
thisArg - дальше идут обычные аргументы функции
call() полезен для “заимствования” метода
Иногда нужно использовать метод одного объекта для другого значения.
Например, старый и известный приём:
function logArguments() {
const result = Array.prototype.join.call(arguments, ", ");
console.log(result);
}
logArguments("a", "b", "c"); // "a, b, c"
Здесь join() из массива используется для псевдомассива arguments.
Это полезно, когда у значения нет нужного метода, но по структуре оно подходит.
call() и методы объекта
Иногда метод выносят из объекта в отдельную переменную, и тогда this теряется.
const user = {
name: "Анна",
showName() {
console.log(this.name);
},
};
const show = user.showName;
show.call(user); // "Анна"
call(user) позволяет явно вернуть нужный контекст.
Чем call() отличается от apply()
Оба метода вызывают функцию сразу и оба работают с this.
Разница в том, как передаются аргументы:
call()принимает аргументы по одномуapply()принимает аргументы массивом
call():
function sum(a, b) {
return a + b;
}
console.log(sum.call(null, 2, 3)); // 5
apply():
function sum(a, b) {
return a + b;
}
console.log(sum.apply(null, [2, 3])); // 5
С появлением spread apply() стали использовать реже, потому что массив теперь легко раскрыть через ....
Чем call() отличается от bind()
Это ещё одно важное различие:
call()вызывает функцию сразуbind()возвращает новую функцию на будущее
Пример:
function greet() {
console.log(this.name);
}
const user = { name: "Анна" };
greet.call(user); // "Анна"
const boundGreet = greet.bind(user);
boundGreet(); // "Анна"
Если выполнить нужно немедленно, подходит call().
Если функцию надо подготовить сейчас, а запустить позже, подходит bind().
call() и стрелочные функции
Со стрелочными функциями call() не даёт обычного эффекта привязки this.
const arrow = () => {
console.log(this);
};
arrow.call({ name: "Анна" });
Синтаксически это работает, но this стрелочной функции не становится объектом из call(), потому что у стрелочных функций нет собственного this.
Поэтому call() обычно используют с обычными функциями.
Когда это полезно
call() особенно удобен, когда:
- нужно сразу вызвать функцию с заданным
this - одна функция должна поработать с разными объектами
- нужно временно использовать метод одного типа данных для другого значения
- надо явно управлять контекстом вызова
Пример:
function printPrice(currency) {
console.log(`${this.price} ${currency}`);
}
const product = { price: 1500 };
printPrice.call(product, "руб.");
Частые ошибки
Путать call() и bind()
function greet() {
console.log(this.name);
}
const user = { name: "Анна" };
const result = greet.call(user);
Здесь result - это не новая функция, а результат выполнения greet.
call() ничего не откладывает на потом.
Забывать, что первый аргумент call() - это this
function greet(message) {
console.log(message, this.name);
}
const user = { name: "Анна" };
greet.call(user, "Привет");
Если перепутать порядок, контекст и аргументы окажутся не там, где ожидаются.
Ожидать, что call() “исправит” this у стрелочной функции
Для стрелочных функций call() обычно не используют для привязки this.
Использовать call() там, где this вообще не нужен
function sum(a, b) {
return a + b;
}
sum.call(null, 2, 3);
Так можно, но если функция не использует this, обычный вызов часто проще:
sum(2, 3);
Пытаться вызвать call() не на функции
const user = {};
// user.call(null); // TypeError
call() - это метод именно функций.
Быстрая памятка
call()- это метод функцийcall()вызывает функцию сразу- первый аргумент
call()- этоthis - остальные аргументы передаются в функцию по одному
call()отличается отapply()способом передачи аргументовcall()отличается отbind()тем, что не возвращает новую функцию- со стрелочными функциями
call()обычно не используют для привязкиthis
Коротко
call() в JavaScript нужен для немедленного вызова функции с указанным this и аргументами. Главное, что стоит запомнить: он похож на apply() и bind(), но работает по-своему, потому что вызывает функцию сразу и принимает аргументы отдельным списком.