JavaScript. Подробное руководство, 6-е издание, стр. 91

8.3.2. Списки аргументов переменной длины: объект Arguments

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

<b>Arguments</b>
. В теле функции идентификатор
<b>arguments</b>
ссылается на объект
<b>Arguments</b>
, присутствующий в вызове. Объект
<b>Arguments</b>
- это объект, подобный массиву (раздел 7.11), позволяющий извлекать переданные функции значения по их номерам, а не по именам.

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

<b>arguments[0].</b>
Второй аргумент будет доступен только как
<b>arguments[1].</b>
Кроме того, подобно настоящим массивам,
<b>arguments</b>
имеет свойство
<b>length</b>
, определяющее количество содержащихся элементов. То есть в теле функции f, вызываемой с двумя аргументами, arguments,
<b>length</b>
имеет значение 2.

Объект

<b>Arguments</b>
может использоваться с самыми разными целями. Следующий пример показывает, как с его помощью проверить, была ли функция вызвана с правильным числом аргументов, - ведь JavaScript этого за вас не сделает:

<b>function f(x, у, z)</b>

<b>{</b>

<b>  // Сначала проверяется, правильное ли количество аргументов передано </b>

<b>  if (arguments.length != 3) {</b>

<b>    throw new Error(&quot;функция f вызвана c ” + arguments.length +</b>

<b>        &quot;аргументами, а требуется 3.&quot;);</b>

<b>  }</b>

<b>  // А теперь сам код функции...</b>

<b>}</b>

Обратите внимание, что зачастую нет необходимости проверять количество аргументов, как в данном примере. Поведение по умолчанию интерпретатора JavaScript отлично подходит для большинства случаев: отсутствующие аргументы замещаются значением

<b>undefined</b>
, а лишние аргументы просто игнорируются.

Объект

<b>Arguments</b>
иллюстрирует важную возможность JavaScript-функций: они могут быть написаны таким образом, чтобы работать с любым количеством аргументов. Следующая функция принимает любое число аргументов и возвращает значение самого большого из них (аналогично ведет себя встроенная функция Math.max()):

<b>function max(/*...*/)</b>

<b>{</b>

<b>  var m = Number.NEGATIVE.INFINITY;</b>

<b>  // Цикл по всем аргументам, поиск и сохранение наибольшего из них</b>

<b>  for(var і = 0; і &lt; arguments.length; i++)</b>

<b>    if (arguments[i] &gt; max) max = arguments[i];</b>

<b>  // Вернуть наибольшее значение return max;</b>

<b>}</b>

<b>var largest = max(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // =&gt; 10000</b>

Функции, подобные этой и способные принимать произвольное число аргументов, называются функциями с переменным числом аргументов (ivariadic functions, variable arity functions или varargs functions). Этот термин возник вместе с появлением языка программирования С.

Обратите внимание, что функции с переменным числом аргументов не должны допускать возможность вызова с пустым списком аргументов. Будет вполне разумным использовать объект

<b>arguments[]</b>
при написании функции, ожидающей получить фиксированное число обязательных именованных аргументов, за которыми может следовать произвольное число необязательных неименованных аргументов.

Не следует забывать, что

<b>arguments</b>
фактически не является массивом - это объект
<b>Arguments</b>
. В каждом объекте
<b>Arguments</b>
имеются пронумерованные элементы массива и свойство
<b>length</b>
, но с технической точки зрения это не массив. Лучше рассматривать его как объект, имеющий некоторые пронумерованные свойства. Подробнее об объектах, подобных массивам, рассказывается в разделе 7.11.

У объекта

<b>Arguments</b>
есть одна очень необычная особенность. Когда у функции имеются именованные параметры, элементы массива объекта
<b>Arguments</b>
при выполнении в нестрогом режиме являются синонимами параметров, содержащих аргументы функции. Массив
<b>arguments[]</b>
и имена параметров - это два разных средства обращения к одним и тем же переменным. Изменение значения аргумента через имя аргумента меняет значение, извлекаемое через массив
<b>arguments[]</b>
. Изменение значения аргумента через массив
<b>arguments[]</b>
меняет значение, извлекаемое по имени аргумента. Например:

<b>function f(x) {</b>

<b>  console.log(x); // Выведет начальное значение аргумента </b>

<b>  arguments[0] = null; // При изменении элемента массива изменяется х! </b>

<b>  console.log(x); // Теперь выведет &quot;null&quot;</b>

<b>}</b>

Определенно, это не совсем то поведение, которое можно было бы ожидать от настоящего массива. В этом случае

<b>arguments[0]</b>
и х могли бы ссылаться на одно и то же значение, но изменение одной ссылки не должно оказывать влияния на другую.

Эта особенность в поведении объекта

<b>Arguments</b>
была ликвидирована в строгом режиме, предусматриваемом стандартом ECMAScript 5. Кроме того, в строгом режиме имеется еще несколько отличий. В нестрогом режиме
<b>arguments</b>
- это всего лишь обычный JavaScript-идентификатор, а не зарезервированное слово. В строгом режиме не допускается использовать имя
<b>arguments</b>
в качестве имени параметра или локальной переменной функции и отсутствует возможность присваивать значения элементам
<b>arguments.</b>