Spec-Zone.ru › JavaScript

Function.prototype.apply()

Базовый уровень Широко доступен

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с июля 2015 года.

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

Попробуйте

const numbers = [5, 6, 2, 3, 7];

const max = Math.max.apply(null, numbers);

console.log(max);
// Expected output: 7

const min = Math.min.apply(null, numbers);

console.log(min);
// Expected output: 2

Синтаксис

apply(thisArg)
apply(thisArg, argsArray)

Параметры

thisArg
Значение this, предоставленное для вызова func. Если функция не находится в строгом режиме, null и undefined будут заменены глобальным объектом, а примитивные значения будут преобразованы в объекты.
argsArray Необязательно
Массивоподобный объект, указывающий аргументы, с которыми должен быть вызван func, или null или undefined, если функции не должны быть переданы никакие аргументы.

Возвращаемое значение

Результат вызова функции с указанным значением this и аргументами.

Описание

Примечание: Эта функция почти идентична call(), за исключением того, что аргументы функции передаются в call() по отдельности списком, тогда как для apply() они объединены в один объект, обычно массив — например, func.call(this, "eat", "bananas") против func.apply(this, ["eat", "bananas"]).

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

Вы также можете использовать любой объект, подобный массиву, в качестве второго параметра. На практике это означает, что он должен иметь свойство length и целочисленные (индексные) свойства в диапазоне (0..length - 1). Например, вы можете использовать NodeList или пользовательский объект, такой как { 'length': 2, '0': 'eat', '1': 'bananas' }. Вы также можете использовать arguments, например:

function wrapper() {
  return anotherFn.apply(null, arguments);
}

С помощью остаточных параметров и синтаксиса расширения параметров это можно переписать следующим образом:

function wrapper(...args) {
  return anotherFn(...args);
}

В целом, fn.apply(null, args) эквивалентен fn(...args) с синтаксисом расширения параметров, за исключением того, что в первом случае args ожидается как массивоподобный объект с apply(), а во втором случае с синтаксисом расширения — как итерируемый объект.

Предупреждение: Не используйте apply() для объединения конструкторов (например, для реализации наследования). Это вызывает функцию-конструктор как обычную функцию, что означает, что new.target равен undefined, а классы выдают ошибку, поскольку их нельзя вызвать без new. Вместо этого используйте Reflect.construct() или extends.

Примеры

Использование apply() для добавления массива в другой

Вы можете использовать Array.prototype.push() для добавления элемента в массив. Поскольку push() принимает переменное количество аргументов, вы также можете добавить несколько элементов одновременно. Но если вы передадите массив в push(), он фактически добавит этот массив как один элемент, а не добавит элементы по отдельности, в итоге получится массив внутри массива. С другой стороны, Array.prototype.concat() имеет желаемое поведение в этом случае, но он не добавляет в *существующий* массив — он создает и возвращает новый массив.

В этом случае вы можете использовать apply для неявного "распределения" массива в виде серии аргументов.

const array = ["a", "b"];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

Тот же эффект может быть достигнут с помощью синтаксиса расширения.

const array = ["a", "b"];
const elements = [0, 1, 2];
array.push(...elements);
console.info(array); // ["a", "b", 0, 1, 2]

Использование apply() и встроенных функций

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

Например, мы можем использовать Math.max() и Math.min() для определения максимального и минимального значения в массиве.

// min/max number in an array
const numbers = [5, 6, 2, 3, 7];

// using Math.min/Math.max apply
let max = Math.max.apply(null, numbers);
// This about equal to Math.max(numbers[0], …)
// or Math.max(5, 6, …)

let min = Math.min.apply(null, numbers);

// vs. loop based algorithm
max = -Infinity;
min = Infinity;

for (const n of numbers) {
  if (n > max) {
    max = n;
  }
  if (n < min) {
    min = n;
  }
}

Но будьте осторожны: используя apply() (или синтаксис расширения) с произвольно длинным списком аргументов, вы рискуете превысить лимит длины аргументов движка JavaScript.

Последствия вызова функции с слишком большим количеством аргументов (то есть более десятков тысяч аргументов) не определены и варьируются в зависимости от движков. (Движок JavaScriptCore имеет жестко заданный предел аргументов в 65536.) Большинство движков выдают исключение; но нет нормативного спецификации, запрещающей другое поведение, такое как произвольное ограничение количества аргументов, фактически передаваемых в примененную функцию. Чтобы проиллюстрировать последний случай: если бы такой движок имел ограничение в четыре аргумента (фактические пределы, конечно, значительно выше), это было бы так, как если бы аргументы 5, 6, 2, 3 были переданы в apply в примерах выше, а не весь массив.

Если ваш массив значений может вырасти до десятков тысяч, используйте гибридную стратегию: применяйте вашу функцию к частям массива за раз:

function minOfArray(arr) {
  let min = Infinity;
  const QUANTUM = 32768;

  for (let i = 0; i < arr.length; i += QUANTUM) {
    const subMin = Math.min.apply(
      null,
      arr.slice(i, Math.min(i + QUANTUM, arr.length)),
    );
    min = Math.min(subMin, min);
  }

  return min;
}

const min = minOfArray([5, 6, 2, 3, 7]);

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-function.prototype.apply

Совместимость с браузерами

Настольные Мобильные Сервер
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
apply
1
12
1
4
1
18
4
10.1
1
1.0
4.4
1
1.0.0
1.0
0.10.0
generic_arrays_as_arguments
17
12
4
5
6
18
4
10.1
6
1.0
4.4
6
1.0.0
1.0
0.10.0

См. также

  • arguments
  • Function.prototype.bind()
  • Function.prototype.call()
  • Reflect.apply()
  • Функции
  • Синтаксис расширения (...)

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API