JavaScript | Объявление функции

JavaScript | Объявление функции

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

Тут речь идёт только о новой функции, которая имеет свой уникальный проектный функционал. Имеется ввиду, что в среде выполнения кода она ранее не была объявлена. И это мы не учитываем всевозможные интерфейсы прикладного программирования, которые работают, например, в браузере (которые тоже являются функциями, но которые знает среда). Сюда мы также не относим все стандартные методы хорошо известных объектов JavaScript.

 

1. Объявление функции через ключевое слово function

Если мы говорим о стандартном Объявлении Функции (Function Declaration), то мы должны знать два производства по стандарту ECMAScript, при помощи которых можно объявить новую функцию. Эти два производства отличаются по сути только присваиванием Идентификатора Привязки (Binding Identifier) для нашей новой функции.

 

Синтаксис именованного объявления функции по стандарту ECMAScript:

FunctionDeclaration [Yield, Await, Default] :

function BindingIdentifier [?Yield, ?Await] ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] }

 

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

FunctionDeclaration [Yield, Await, Default] :

[+Default] function ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] }

 

Пример именованной функции JavaScript

function getZ (){}

Идентификатор привязки назвали «getZ»

Объявили именованную функцию с идентификатором привязки - JavaScript
Объявили именованную функцию с идентификатором привязки — JavaScript

 

Пример безымянной функции JavaScript

function (){}

Идентификатор привязки отсутствует, поэтому в таком виде её нельзя использовать в качестве отдельной команды Скрипта.

Но её можно использовать при передаче параметров в какую-нибудь другую функцию

 

Безымянная функция

Попытка объявления безымянной функции на верхнем «уровне видимости» нашего Скрипта, приведёт к синтаксической ошибке:

Синтаксическая ошибка объявления безымянной функции в Скрипте - JavaScript
Синтаксическая ошибка объявления безымянной функции в Скрипте — JavaScript

То есть в качестве отдельной команды нельзя использовать безымянный вид объявления функции.

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

Применение безымянной функции в методе map для экземпляра Array - JavaScript
Применение безымянной функции в методе map для экземпляра Array — JavaScript

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

 

Важно отметить то, что в обоих примерах мы используем ключевое слово «function«, которое является Зарезервированным Словом (Reserved Word) в JavaScript. Также у нас в обоих случаях встречаются:

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

Оба блока пустые. Это сделано специально для того, чтобы понимать самое минимальное требование, необходимое для объявления функции. В наших примерах обе функции НИЧЕГО не делают, но объявлены.

 

Браузер и объект Window

Все именованные функции, объявленные через ключевое слово «function» поселяются жить в виде нового свойства для ГЛОБАЛЬНОГО объекта JavaScript. В браузере это объект Window.

Объявленная именованная функция поселилась в виде свойства ГЛОБАЛЬНОГО объекта - JavaScript
Объявленная именованная функция поселилась в виде свойства ГЛОБАЛЬНОГО объекта — JavaScript

 

 

2. Объявление стрелочных функций

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

  1. В случае с функциями-стрелками мы уже не используем Зарезервированное Слово «function«. Оно просто отпадает.
  2. Функции стрелки по умолчанию предполагают возврат какого-либо значения (оформлено символами =>).

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

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

ArrowFunction [In, Yield, Await] :

ArrowParameters [?Yield, ?Await] [не LineTerminator здесь] => ConciseBody [?In]

 

Пример безымянной стрелочной функции JavaScript без аргументов

Лаконичное Тело оформлено в виде FunctionBody

()=>{}

Объявили самую простую стрелочную функцию с лаконичным телом вида FunctionBody - JavaScript
Объявили самую простую стрелочную функцию с лаконичным телом вида FunctionBody — JavaScript

 

Пример безымянной стрелочной функции JavaScript без аргументов

Лаконичное Тело оформлено в виде ExpressionBody

()=>x

Объявили самую простую стрелочную функцию с лаконичным телом вида ExpressionBody - JavaScript
Объявили самую простую стрелочную функцию с лаконичным телом вида ExpressionBody — JavaScript

 

Пример безымянной стрелочной функции JavaScript с одним аргументом

Лаконичное Тело оформлено в виде FunctionBody. Один аргумент можно не покрывать круглыми скобками.

z=>{z+1}

Один аргумент можно покрыть круглыми скобками.

(z)=>{z+1}

Стрелочная функция с одним аргументом. Лаконичное Тело оформлено в виде FunctionBody - JavaScript
Стрелочная функция с одним аргументом. Лаконичное Тело оформлено в виде FunctionBody — JavaScript
Стрелочная функция с одним покрытым аргументом. Лаконичное Тело оформлено в виде FunctionBody - JavaScript
Стрелочная функция с одним покрытым аргументом. Лаконичное Тело оформлено в виде FunctionBody — JavaScript

 

Пример безымянной стрелочной функции JavaScript с одним аргументом

Лаконичное Тело оформлено в виде ExpressionBody. Один аргумент можно не покрывать круглыми скобками.

z=>z+1

Один аргумент можно покрыть круглыми скобками.

(z)=>z+1

Стрелочная функция с одним аргументом. Лаконичное Тело оформлено в виде ExpressionBody - JavaScript
Стрелочная функция с одним аргументом. Лаконичное Тело оформлено в виде ExpressionBody — JavaScript
Стрелочная функция с одним покрытым аргументом. Лаконичное Тело оформлено в виде ExpressionBody - JavaScript
Стрелочная функция с одним покрытым аргументом. Лаконичное Тело оформлено в виде ExpressionBody — JavaScript

 

Примеры стрелочных функций JavaScript с двумя аргументами

(q, w)=>{q+w}

(q, w)=>q+w

 

3. Объявление функции через конструктор класса Function

Примеры

Function()

new Function()

Объявление функции через конструктор класса Function - JavaScript
Объявление функции через конструктор класса Function — JavaScript
Объявление функции через конструктор класса Function с оператором new - JavaScript
Объявление функции через конструктор класса Function с оператором new — JavaScript

 

 

Синтаксис определения функции

FunctionDeclaration [Yield, Await, Default] :

function BindingIdentifier [?Yield, ?Await] ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] }

[+Default] function ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] }

 

FunctionExpression :

function BindingIdentifier [~Yield, ~Await] opt ( FormalParameters [~Yield, ~Await] ) { FunctionBody [~Yield, ~Await] }

 

FunctionBody [Yield, Await] :

FunctionStatementList [?Yield, ?Await]

 

FunctionStatementList [Yield, Await] :

StatementList [?Yield, ?Await, +Return] opt

 

Синтаксис Определения Стрелочных Функций

ArrowFunction [In, Yield, Await] :

ArrowParameters [?Yield, ?Await] [не LineTerminator здесь] => ConciseBody [?In]

 

ArrowParameters [Yield, Await] :

BindingIdentifier [?Yield, ?Await]

CoverParenthesizedExpressionAndArrowParameterList [?Yield, ?Await]

 

ConciseBody [In] :

[lookahead ≠ {] ExpressionBody [?In, ~Await]

{ FunctionBody [~Yield, ~Await] }

 

ExpressionBody [In, Await] :

AssignmentExpression [?In, ~Yield, ?Await]

 

Информационные ссылки

Стандарт ECMAScript — Раздел «15.2 Function Definitions» — https://tc39.es/ecma262/#sec-function-definitions