Есть ли максимальное количество аргументов, которые могут выполнять функции JavaScript?
Я знаю, что функции JavaScript могут принимать "любое" количество аргументов.
function f(){};
f(1,2,3,4 /*...*/);
Но мне интересно, действительно ли существует ограничение на количество "каких-либо"?
Например, скажем, я передаю миллион аргументов f()
. Будет ли это работать? Или кипеть переводчик?
Я предполагаю, что максимум является либо (a) специфичным для реализации, либо (b) (2^32)-1
, поскольку объект arguments
имеет тип массива.
Я не вижу этого в спецификации языка, но я мог бы не подключать некоторые точки.
Ответы
Ответ 1
Хотя нет ничего конкретного ограничения теоретического максимального количества аргументов в spec (как ответ на фортешев). Конечно, существуют практические ограничения. Эти ограничения полностью зависят от реализации и, скорее всего, также будут зависеть именно от того, как вы вызываете функцию.
Я создал эту скрипту в качестве эксперимента.
function testArgs() {
console.log(arguments.length);
}
var argLen = 0;
for (var i = 1; i < 32; i++) {
argLen = (argLen << 1) + 1;
testArgs.apply(null, new Array(argLen));
}
Вот мои результаты:
-
Chrome 33.0.1750.154 m: Последнее успешное тестирование было 65535. После этого он не удался:
Uncaught RangeError: максимальный размер стека вызовов
-
Firefox 27.0.1: последним успешным тестом было 262143. После этого он не удался:
RangeError: массив аргументов, переданный в Function.prototype.apply слишком большой
-
Internet Explorer 11: последним успешным тестом были аргументы 131071. После этого он не удался:
RangeError: SCRIPT28: из пространства стека
-
Opera 12.17: Последнее успешное тестирование было 1048576. После этого он не удался:
Ошибка: Function.prototype.apply: argArray слишком велико
Конечно, здесь могут быть и другие факторы, и у вас могут быть разные результаты.
А вот альтернативная скрипта, созданная с помощью eval
. Опять же, вы можете получить разные результаты.
-
Chrome 33.0.1750.154 m: Последнее успешное тестирование было 32767. После этого он не удался:
Uncaught SyntaxError: Слишком много аргументов в вызове функции (разрешено только 32766)
Это особенно интересно, потому что сам Chrome, похоже, путается о том, сколько аргументов действительно разрешено.
-
Firefox 27.0.1: последним успешным тестом было 32767. После этого он не удался:
script слишком большой
-
Internet Explorer 11: последний успешный тест был 32767. После этого он не удался:
RangeError: SCRIPT7: Недостаточно памяти
-
Opera 12.17: Последнее успешное тестирование было 4194303. После этого он не удался:
Недостаточно памяти; script завершено.
Ответ 2
ECMAScript 5.1, часть 8.8
Тип List используется для объяснения оценки списков аргументов (см. 11.2.4) в новых выражениях, в вызовах функций и в других алгоритмах, где необходим простой список значений... Эти последовательности могут быть любой длины.
Таким образом, в стандарте нет предела. Конечно, если ваш код работает в реальном мире, а не в стандартах, то есть, очевидно, некоторый предел (например, количество частиц во Вселенной).
Есть два способа передать параметры функции.
- "Буквально":
f(a, b, c)
- С apply():
f.apply(null, [a, b, c])
Этот последний способ является более реалистичным сценарием для больших списков аргументов.
Перейдите к этому JSFiddle, чтобы увидеть ограничения для каждого из них для вашего текущего браузера.
Я сам опробовал несколько браузеров:
| apply() | literal
----------------------------
Chrome 14 | 131155 | 32767
Chrome 35 | 126213 | 65535
Firefox 30 | 500001 | 65535
IE 9 | 254335 | 65533
IE 10 | 253667 | 65533
IE 11 | 252447 | 65533
Opera 22 | 126063 | 65535
Safari 4 | 524215 | 524205
Safari 7 | 65537 | 522159
Я видел различия во многих из этих чисел на разных машинах, поэтому я считаю, что есть другие факторы, помимо браузера (ОС?).
Это реальная проблема,, а не некоторые мелочи. Пример в реальном мире:
В Google Closure Library определена следующая функция.
goog.crypt.byteArrayToString = function(array) {
return String.fromCharCode.apply(null, array);
};
Это работало, только если длина строки находилась в пределах браузера для количества аргументов, которые могут быть переданы с помощью Function.prototype.apply
.
Функция была позже исправлена , что значительно усложнило функцию.
FYI, есть открытая проблема Webkit, поданная в марте 2012 года, в которой обсуждается ограничение аргумента.
Ответ 3
Согласно стандарту ECMA Script 5.1 для List
,
Тип List используется для объяснения оценки списков аргументов (см. 11.2.4) в новых выражениях, вызовах функций и в других алгоритмах, где необходим простой список значений. Значения типа List - это просто упорядоченные последовательности значений. Эти последовательности могут иметь любую длину.
Таким образом, стандарт не имеет ограничений на количество аргументов и ограничен только памятью.
Ответ 4
![Computer Stupidities]()
> от компьютерных глупостей
Насколько мне известно, предел "достаточно большой"!
Ответ 5
Это зависит от того, насколько мощным является клиент.
Поскольку браузер потеряет свою память, если вы собираетесь передать миллионы аргументов.
Каждая переменная содержит некоторую память. Поэтому у браузеров не будет проблем с распределением каждой переменной некоторой памяти, пока она сама не будет иметь памяти для запуска.
Ответ 6
Согласно разделу функции JavaScript MDN, максимальное количество параметров, которые может принять функция, составляет 255.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Defining_functions
param The name of an argument to be passed to the function. A function can have up to 255 arguments.
Ответ 7
Вот как я это проверяю.
let args = [];
while(true){
try{
(() => {})(...args);
args.push(0);
}catch(e){
console.log(e.message);
console.log('Number of arguments: ${args.length}');
break;
}
}