Что такое метод apply в JavaScript?

Ответ

Метод apply() — это встроенный метод функции, который позволяет вызвать её с заданным значением this и аргументами, переданными в виде массива (или массивоподобного объекта). Это ключевой инструмент для управления контекстом выполнения.

Основное отличие от call(): call() принимает список аргументов, а apply() — массив аргументов.

Пример использования:

function introduce(role, project) {
    console.log(`Меня зовут ${this.name}, я ${role} в проекте ${project}.`);
}

const developer = { name: 'Анна' };

// Вызываем функцию introduce, устанавливая developer как контекст (this)
// и передаём аргументы ['бэкенд-разработчик', 'API Gateway'] как массив.
introduce.apply(developer, ['бэкенд-разработчик', 'API Gateway']);
// Вывод: Меня зовут Анна, я бэкенд-разработчик в проекте API Gateway.

Технические детали:

  • Первый аргумент: Значение, которое станет this внутри вызываемой функции. Если передать null или undefined, в нестрогом режиме this будет ссылаться на глобальный объект (в браузере — window, в Node.js — global).
  • Второй аргумент: Массив (или объект с length, например arguments), элементы которого становятся аргументами функции.
  • Практическое применение в Node.js: Исторически apply() был полезен для вызова функций с переменным числом аргументов или для передачи массива данных. С появлением оператора расширения (...) его использование сократилось, но понимание метода важно для работы с унаследованным кодом и для низкоуровневых операций с функциями.

Ответ 18+ 🔞

Да ты посмотри, какой прикольный инструмент подкинули в JavaScript — этот apply(). Ну реально, хитрая жопа, а не метод. Представь себе: у тебя есть функция, и ты хочешь её запустить, но так, чтобы внутри неё слово this значило совсем не то, что обычно, а какой-то твой объект. И заодно запихнуть в неё аргументы не по одному, а целым массивом сразу. Вот для этого apply() и существует.

Чем он от call() отличается, спросишь? Да всё просто, как божий день. call() ждёт, чтобы ты аргументы через запятую перечислил, а apply() — чтобы ты их в массив запихал и этот массив ему сунул. Вот и вся разница, ёпта.

Смотри, как это в деле выглядит:

function introduce(role, project) {
    console.log(`Меня зовут ${this.name}, я ${role} в проекте ${project}.`);
}

const developer = { name: 'Анна' };

// Берём функцию introduce, насильно делаем так, чтобы this был объектом developer,
// и засовываем ей в рот аргументы массивом ['бэкенд-разработчик', 'API Gateway'].
introduce.apply(developer, ['бэкенд-разработчик', 'API Gateway']);
// Напечатает: Меня зовут Анна, я бэкенд-разработчик в проекте API Gateway.

А теперь по косточкам разберём, как эта мартышлюшка работает:

  • Первый аргумент — это то, во что превратится this внутри функции. Кинешь туда null или undefined — и в нестрогом режиме this полетит прямиком в глобальный объект (window или global). Доверия к такому поведению, блядь, ноль, так что осторожнее.
  • Второй аргумент — это массив (или что-то похожее на массив, та же arguments). Всё, что в нём лежит, станет аргументами для вызова. Удобно, когда их овердохуища и они уже в массиве собраны.
  • Зачем это сейчас нужно? Честно? Раньше без apply() вообще тяжко было, когда аргументы динамически формировались. Но теперь-то есть оператор расширения (...), которым можно сделать то же самое: introduce(...developer, ...['бэкенд', 'API']). Однако понимать apply() всё равно надо — мало ли, в каком-нибудь древнем легаси-коде на него наткнёшься, или для каких хитрых трюков с функциями пригодится. Без него как без рук.