Функции JavaScript

В этой главе:

  • Функции как объекты первого класса

  • Определение и вызов функции

  • Параметры и аргументы

  • Инструкция return

  • Выбор имени функции

  • Подъём определения функции

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

Функции как объекты первого класса

В JavaScript объекты обладают определёнными свойствами:

  • Их можно создавать с помощью литералов

  • Их можно присваивать переменным, элементам массива и свойствам других объектов

  • Их можно передавать в качестве аргументов функциям

  • Их можно возвращать в качестве значений из функций

  • Они могут обладать свойствами, которые допускается создавать и присваивать динамически

Функции в JavaScript обладают всеми этими свойствами, а следовательно, их можно рассматривать в данном языке как и любой другой объект. Именно поэтому функции и называются объектами первого класса. Но помимо того что к функциям следует относится как и к другим типам объектов, они обладают особым свойством: их можно вызывать.

Определение и вызов функции

Функция определяется с помощью ключевого слова function, за которым указываются следующие компоненты:

  • Идентификатор, определяющий имя функции.

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

  • Блок кода состоящий из пары фигурных скобок с нулём или более инструкций. Этот блок кода является телом функции и выполняется при каждом вызове функции.

Синтаксис определения функции выглядит следующим образом:

1
function имя_функции(параметры) { инструкции }

Простой пример определения функции:

1
2
3
4
5
function starline() {
  for(var i = 0; i < 45; i++) {
    document.write("*");
  }
}

Несмотря на то, что приведённая в примере функция короткая и простая, она содержит все перечисленные компоненты.

Программный код, расположенный в теле функции, выполняется не в момент определения функции, а в момент её вызова. Для вызова функции используется оператор вызова, представляющий из себя пару круглых скобок (). Оператор вызова указывается после имени функции, которая вызывается на выполнение. Он инициирует выполнение самой функции. Это означает, что управление передаётся инструкциям расположенным в теле функции. После своего выполнения, управление передаётся инструкции, следующей за вызовом функции. Завершается вызов функции как и все инструкции точкой с запятой (;):

1
2
3
starLine();
document.write("<p>это абзац</p>");
starLine();

Параметры и аргументы

Как уже было сказано, определение функции может включать в себя список идентификаторов (параметры функции), которые играют роль локальных переменных в теле функции. При указании параметров функции ключевое слово var использовать не нужно, JavaScript объявляет их в качестве локальных переменные автоматически. Параметров может быть указано любое количество:

1
function foo(a,b,c) { ... }  // a,b,c - параметры функции

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

1
2
3
4
5
6
function foo(a,b) {
  var c = a + b;
  alert(c);
}
 
foo(5, 7);

Когда при вызове функции ей передаётся список аргументов, эти аргументы присваиваются параметрам функции в том порядке, в каком они указаны: первый аргумент присваивается первому параметру, второй аргумент второму параметру и т.д. Если число аргументов отличается от числа параметров, то никакой ошибки не происходит. В JavaScript подобная ситуация разрешается следующим образом:

  • Если при вызове функции ей передаётся больше аргументов, чем задано параметров, "лишние" аргументы просто не присваиваются параметрам. Допустим, имеется следующее определение функции:

    1
    function foo(a,b,c) { ... }

    Если при её вызове указать foo(1,2,3,4,5), то аргументы 1,2 и 3 будут присвоены параметрам a,b и c соответственно. В то же время аргументы 4 и 5 не будут присвоены ни одному из параметров данной функции.

  • Если функция имеет больше параметров, чем передано ей аргументов, то параметрам без соответствующих аргументов присваивается значение undefined. Так, если при вызове функции foo(a,b,c) указать foo(1), параметру a будет присвоено значение 1, а параметрам b и c - значение undefined.

    1
    2
    3
    4
    5
    function foo(a,b,c) {
      document.write(a+"<br>"+b+"<br>"+c);
    }
     
    foo(1);

Инструкция return

Функция может возвратить некоторое значение (результат работы функции) программе, которая её вызвала. Возвращаемое значение передаётся в точку вызова функции.

Инструкция return внутри функции служит для определения значения, возвращаемого функцией. В качестве возвращаемого значения может быть значение любого типа. Если в качестве возвращаемого значения используется выражение, в программу возвращается не само выражение, а результат его вычисления. Инструкция return имеет следующий синтаксис:

1
return выражение;

Для дальнейшего использования возвращаемого значения, результат выполнения функции можно присвоить например переменной:

1
2
3
4
5
6
7
function calc(a) {
  return a * a;
}
 
var x = calc(5);
 
document.write(x);

Инструкция return может быть расположена в любом месте функции. Обратите внимание, при выполнении кода внутри функции, как только будет достигнута инструкция return, функция возвращает значение и немедленно завершает своё выполнение. Код, расположенный в теле функции после инструкции return, будет проигнорирован.

1
2
3
4
5
6
7
8
9
10
11
var a = 1;
 
function foo() {
  ++a;
  return;
  ++a;
}
 
foo();
 
document.write(a);  // => 2

Внутри функции может быть использовано несколько инструкций return, например если возвращаемое значение зависит от некоторых условий выполнения:

1
2
3
4
5
6
function check(a, b) {
  if(a > b) return a;
  else return b;
}
 
document.write(check(3, 5));

Если инструкция return не указана или не указано возвращаемое значение, то функция вернёт значение undefined.

1
2
3
4
5
6
7
8
9
10
11
12
13
// Инструкция return не указана
function bar() { document.write("функция bar выполнилась"); }
 
// Возвращаемое значение не указано
function foo(a) {
  if(!a) return;
  document.write(a);
}
 
var a = bar(); // undefined
var b = foo(); // undefined
 
document.write("a: " + a + "<br> b: " + b);

Выбор имени функции

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

Подъём определения функции

Определение функции неявно "поднимается" в начало сценария или вмещающей её (внешней) функции, благодаря чему функцию можно вызвать ещё до того, как она будет определена.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
foo();
bar();
 
function foo() {
  alert("Hello!");
}
 
function bar() {
  var str = "Hello again!";
  foo();
 
  function foo() {
    document.write(str);
  }
}

Таким образом функции выше эквивалентны определениям функций приведённым ниже, в которых определения "подняты" в начало.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function foo() {
  alert("Hello!");
}
 
function bar() {
  function foo() {
    document.write(str);
  }
 
  var str = "Hello again!";
  foo();
}
 
foo();
bar();