Обратите внимание, что большинство (но не все) функций в примере 8.1 содержат инструкцию
<b>return</b>
(раздел 5.6.4). Инструкция
<b>return</b>
завершает выполнение функции и выполняет возврат значения своего выражения (если указано) вызывающей программе. Если выражение в инструкции
<b>return</b>
отсутствует, она возвращает значение
<b>undefined</b>
. Если инструкция
<b>return</b>
отсутствует в функции, интерпретатор просто выполнит все инструкции в теле функции и вернет вызывающей программе значение
<b>undefined</b>
.
Большинство функций в примере 8.1 вычисляют некоторое значение, и в них инструкция
<b>return</b>
используется для возврата этого значения вызывающей программе. Функция
<b>printprops()</b>
несколько отличается в этом смысле: ее работа заключается в том, чтобы вывести имена свойств объекта. Ей не нужно возвращать какое-либо значение, поэтому в функции отсутствует инструкция
<b>return</b>
. Функция
<b>printprops()</b>
всегда будет возвращать значение
<b>undefined</b>
. (Функции, не имеющие возвращаемого значения, иногда называются процедурами.)
8.1.1. Вложенные функции
В JavaScript допускается вложение определений функций в другие функции. Например:
<b>function hypotenuse(a, b) {</b>
<b> function square(x) { return x*x; }</b>
<b> return Math.sqrt(square(a) + square(b));</b>
<b>}</b>
Особый интерес во вложенных функциях представляют правила видимости переменных: они могут обращаться к параметрам и переменным, объявленным во вмещающей функции (или функциях). Например, в определении выше внутренняя функция
<b>square()</b>
может читать и изменять параметры а и Ь, объявленные во внешней функции
<b>hypotenuse().</b>
Эти правила видимости, действующие для вложенных функций, играют важную роль, и мы еще вернемся к ним в разделе 8.6.
Как отмечалось в разделе 5.3.2, инструкции объявления функций в действительности не являются настоящими инструкциями, и спецификация ECMAScript допускает использовать их только в программном коде верхнего уровня. Они могут появляться в глобальном программном коде или внутри других функций, но они не могут находиться внутри циклов, условных инструкций, инструкций
<b>try/catch/finally</b>
или with.
[11] Обратите внимание, что эти ограничения распространяются только на объявления функций в виде инструкции
<b>function</b>
. Выражения определения функций могут присутствовать в любом месте в программе на языке JavaScript.
8.2. Вызов функций
Программный код, образующий тело функции, выполняется не в момент определения функции, а в момент ее вызова. Функции в языке JavaScript могут вызываться четырьмя способами:
• как функции,
• как методы,
• как конструкторы и
• косвенно, с помощью их методов саll() и
<b>аррlу().</b>
8.2.1. Вызов функций
Вызов функций как функций или как методов, выполняется с помощью выражения вызова (раздел 4.5). Выражение вызова состоит из выражения обращения к функции, которое возвращает объект функции, и следующими за ним круглыми скобками со списком из нуля или более выражений-аргументов, разделенных запятыми, внутри. Если выражение обращения к функции является выражением обращения к свойству - если функция является свойством объекта или элементом массива - тогда выражение вызова является выражением вызова метода. Этот случай будет описан ниже. В следующем фрагменте демонстрируется несколько примеров выражений вызова обычных функций:
<b>printprops({х:1});</b>
<b>var total = distance(0,0,2,1) + distanced, 1,3, 5); </b>
<b>var probability = factorial(5)/factorial(13);</b>
При вызове функции вычисляются все выражения-аргументы (указанные между скобками), и полученные значения используются в качестве аргументов функции. Эти значения присваиваются параметрам, имена которых перечислены в определении функции. В теле функции выражения обращений к параметрам возвращают значения соответствующих аргументов.
При вызове обычной функции возвращаемое функцией значение становится значением выражения вызова. Если возврат из функции происходит по достижении ее конца интерпретатором, возвращается значение
<b>undefined</b>
. Если возврат из функции происходит в результате выполнения инструкции
<b>return</b>
, возвращается значение выражения, следующего за инструкцией
<b>return</b>
, или
<b>undefined</b>
, если инструкция
<b>return</b>
не имеет выражения.
При вызове функции в ECMAScript 3 и в нестрогом режиме ECMAScript 5 контекстом вызова (значением
<b>this</b>
) является глобальный объект. Однако в строгом режиме контекстом вызова является значение
<b>undefined</b>
.
Функции, которые предназначались для использования в виде простых функций, обычно вообще не используют ключевое слово
<b>this</b>
. Впрочем, его можно использовать, чтобы определить, не выполняется ли функция в строгом режиме:
<b>// Определение и вызов функции, которая выясняет действующий режим работы, </b>
<b>var strict = (function() { return !this; }());</b>
Составление цепочек вызовов методов
Когда методы возвращают объекты, появляется возможность использовать значение, возвращаемое одним методом, как часть последующих вызовов. Это позволяет создавать последовательности («цепочки», или «каскады») вызовов методов в одном выражении. При работе с библиотекой
<b>jQuery</b>
(глава 19), например, часто можно встретить такие инструкции:
<b>// Отыскать все заголовки, отобразить их в значения атрибутов id,</b>
<b>// преобразовать в массив и отсортировать</b>
<b>$( ":header").map(function() { return this.id )).get().sort();</b>