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]);
Спецификации
Совместимость с браузерами
| Настольные | Мобильные | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 |
См. также
argumentsFunction.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