Learn JavaScript

apply() - метод для вызова функции с this и массивом аргументов в JavaScript

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(), но удобен именно тогда, когда аргументы уже собраны в массив или массивоподобное значение.