apply() в JavaScript

apply() - это метод функции, который вызывает функцию с указанным значением this.

Главная особенность apply() в том, что аргументы функции передаются массивом.

function greet(message) {
  console.log(message + ', ' + this.name + '!');
}

let user = {
  name: 'Анна'
};

greet.apply(user, ['Привет']);

Результат:

Привет, Анна!

Что такое apply()

apply() похож на call(). Он тоже вызывает функцию сразу и позволяет вручную указать this.

function showName() {
  console.log(this.name);
}

let user = {
  name: 'Игорь'
};

showName.apply(user);

Результат:

Игорь

Внутри функции this указывает на объект user.

Синтаксис

Запись выглядит так:

functionName.apply(thisValue, [argument1, argument2]);

Первый аргумент apply() задает значение this.

Второй аргумент - массив значений, которые будут переданы в функцию.

function getFullInfo(city, job) {
  return this.name + ', ' + city + ', ' + job;
}

let user = {
  name: 'Мария'
};

console.log(getFullInfo.apply(user, ['Москва', 'Frontend developer']));

Результат:

Мария, Москва, Frontend developer

Передача this

Как и у call(), первый аргумент apply() нужен для передачи this.

function showRole() {
  console.log(this.name + ': ' + this.role);
}

let admin = {
  name: 'Анна',
  role: 'admin'
};

showRole.apply(admin);

Результат:

Анна: admin

Функция showRole() не лежит внутри объекта admin, но через apply() она может использовать его данные.

Аргументы массивом

Если функции нужны аргументы, они передаются вторым параметром в виде массива.

function createMessage(greeting, punctuation) {
  return greeting + ', ' + this.name + punctuation;
}

let user = {
  name: 'Ольга'
};

console.log(createMessage.apply(user, ['Здравствуйте', '!']));

Результат:

Здравствуйте, Ольга!

Строка ‘Здравствуйте’ попадет в параметр greeting, а строка ’!’ - в параметр punctuation.

apply() и call()

Разница между apply() и call() только в способе передачи аргументов.

call() принимает аргументы через запятую.

createMessage.call(user, 'Привет', '!');

apply() принимает аргументы массивом.

createMessage.apply(user, ['Привет', '!']);

Оба варианта вызывают функцию сразу.

Пример с Math.max()

Раньше apply() часто использовали, чтобы передать массив в функцию, которая ждет отдельные аргументы.

let numbers = [4, 10, 2, 8];

console.log(Math.max.apply(null, numbers));

Результат:

10

Math.max() не использует this, поэтому первым аргументом передали null.

В современном коде для такой задачи чаще используют spread-оператор.

console.log(Math.max(...numbers));

Но apply() все еще встречается в старом коде, поэтому его важно понимать.

apply() и стрелочные функции

apply() не меняет this у стрелочных функций.

let user = {
  name: 'Анна'
};

const showName = () => {
  console.log(this.name);
};

showName.apply(user);

Стрелочная функция берет this из внешней области видимости, поэтому передача объекта через apply() не работает так, как у обычной функции.

Итого

1. apply() вызывает функцию сразу.

2. Первый аргумент apply() задает значение this.

3. Второй аргумент apply() - массив аргументов для функции.

4. apply() отличается от call() только способом передачи аргументов.

5. У стрелочных функций apply() не меняет this.