Подтвердить что ты не робот

Есть ли максимальное количество аргументов, которые могут выполнять функции JavaScript?

Я знаю, что функции JavaScript могут принимать "любое" количество аргументов.

function f(){};
f(1,2,3,4 /*...*/);

Но мне интересно, действительно ли существует ограничение на количество "каких-либо"?

Например, скажем, я передаю миллион аргументов f(). Будет ли это работать? Или кипеть переводчик?

Я предполагаю, что максимум является либо (a) специфичным для реализации, либо (b) (2^32)-1, поскольку объект arguments имеет тип массива.

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

4b9b3361

Ответ 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

Это зависит от того, насколько мощным является клиент.

Поскольку браузер потеряет свою память, если вы собираетесь передать миллионы аргументов.

Каждая переменная содержит некоторую память. Поэтому у браузеров не будет проблем с распределением каждой переменной некоторой памяти, пока она сама не будет иметь памяти для запуска.

Ответ 7

Вот как я это проверяю.

let args = [];

while(true){
    try{
        (() => {})(...args);
        args.push(0);
    }catch(e){
        console.log(e.message);
        console.log('Number of arguments: ${args.length}');
        break;
    }
}