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