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

8.7.1. Свойство length

В теле функции свойство

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

В следующем фрагменте определяется функция с именем

<b>check(),</b>
получающая массив аргументов
<b>arguments</b>
от другой функции. Она сравнивает свойство
<b>arguments.length</b>
(число фактически переданных аргументов) со свойством
<b>arguments. callee.length</b>
(число ожидаемых аргументов), чтобы определить, передано ли функции столько аргументов, сколько она ожидает. Если значения не совпадают, генерируется исключение. За функцией
<b>check()</b>
следует тестовая функция
<b>f()</b>
, демонстрирующая порядок использования функции
<b>check():</b>

<b>// Эта функция использует arguments.callee, поэтому она </b>

<b>// не будет работать в строгом режиме, </b>

<b>function check(args) {</b>

<b>  var actual = args.length; // Фактическое число аргументов</b>

<b>  var expected = args.callee.length; // Ожидаемое число аргументов </b>

<b>  if (actual !== expected) // Если не совпадают, генерируется исключение</b>

<b>    throw new Еrror(&quot;ожидается: &quot; + expected + получено &quot; + actual);</b>

<b>}</b>

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

<b>  // Проверить число ожидаемых и фактически переданных аргументов. </b>

<b>  check(arguments);</b>

<b>  // Теперь выполнить оставшуюся часть функции как обычно </b>

<b>  return х + у + z;</b>

<b>}</b>

8.7.2. Свойство prototype

Любая функция имеет свойство prototype, ссылающееся на объект, известный как объект прототипа. Каждая функция имеет свой объект прототипа. Когда функция используется в роли конструктора, вновь созданный объект наследует свойства этого объекта прототипа. Прототипы и свойство prototype обсуждались в разделе 6.1.3, и мы еще раз вернемся к этим понятиям в главе 9.

8.7.3. Методы call() и apply()

Методы

<b>саll()</b>
и
<b>аррlу()</b>
позволяют выполнять косвенный вызов функции (раздел 8.2.4), как если бы она была методом некоторого другого объекта. (Мы уже использовали метод
<b>саll()</b>
в примере 6.4 для вызова
<b>Object.prototype.toString </b>
относительно объекта, класс которого необходимо было определить.) Первым аргументом обоим методам,
<b>саll()</b>
и
<b>аррlу(),</b>
передается объект, относительно которого вызывается функция; этот аргумент определяет контекст вызова и становится значением ключевого слова
<b>this</b>
в теле функции. Чтобы вызвать функцию
<b>f()</b>
(без аргументов) как метод объекта о, можно использовать любой из методов,
<b>саll()</b>
или
<b>аррlу():</b>

<b>f.call(о); </b>

<b>f.apply(o);</b>

Любой из этих способов вызова эквивалентен следующему фрагменту (где предполагается, что объект о не имеет свойства с именем m):

<b>о.m = f; // Временно сделать f методом о. </b>

<b>о.m(); // Вызывать его без аргументов,</b>

<b>delete о.m; // Удалить временный метод.</b>

В строгом режиме ECMAScript 5 первый аргумент методов

<b>саll()</b>
и
<b>apply()</b>
становится значением
<b>this</b>
, даже если это простое значение,
<b>null</b>
или
<b>undefined</b>
. В ECMAScript 3 и в нестрогом режиме значения
<b>null</b>
и
<b>undefined</b>
замещаются глобальным объектом, а простое значение - соответствующим объектом-оберткой.

Все остальные аргументы метода

<b>саll(),</b>
следующие за первым аргументом, определяющим контекст вызова, передаются вызываемой функции. Например, ниже показано, как можно передать функции
<b>f()</b>
два числа и вызвать ее, как если бы она была методом объекта о:

<b>f.call(o, 1, 2);</b>

Метод

<b>аррlу()</b>
действует подобно методу
<b>саll(),</b>
за исключением того, что аргументы для функции передаются в виде массива:

<b>f.apply(o, [1,2]);</b>

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

<b>apply()</b>
может использоваться для вызова такой функции в контексте массива произвольной длины. Например, чтобы отыскать наибольшее число в массиве чисел, для передачи элементов массива функции
<b>Math.max()</b>
можно было бы использовать метод
<b>ар ply ():</b>

<b>var biggest = Math.max.apply(Math, array_of_numbers);</b>

Обратите внимание, что метод

<b>apply()</b>
может работать не только с настоящими массивами, но и с объектами, подобными массивам. В частности, вы можете вызвать функцию с теми же аргументами, что и текущую функцию, передав массив с аргументами непосредственно методу
<b>аррlу().</b>
Этот прием демонстрируется ниже: