JavaScript | Функции (Function)

Функции в JavaScript — это маленькие программки, которые выполняют разные специфичные задачи.

 

Что нужно знать про функции?

Условно все функции можно разделить на 3 состояния:

  1. Функция может быть ОБЪЯВЛЕНА (т. е. тело функции содержит саму информацию о работе функции — что, куда и как)
  2. Функция может быть ВЫЗВАНА (т. е. функция выполнит задание по алгоритму, прописанному в теле функции)
  3. Функция может быть ПЕРЕДАНА. На функцию можноp сослаться в асинхронных операциях (т. е. когда мы хотим передать функцию в качестве параметра другой функции)

Что делают функции?

Все функции можно поделить на 2 категории:

  1. Функции ВОЗВРАЩАЮТ
  2. Функции ДЕЛАЮТ (обновляют, запускают, останавливают, удаляют, создают)

Функции, которые что-то ВОЗВРАЩАЮТ получают на вход параметры (данные). Потом внутри тела функции с этими параметрами происходят преобразования. После преобразований результат ВОЗВРАЩАЕТСЯ для дальнейшего использования в алгоритме.

function verni (a,b,c){
   return a*b*c
}
Функция verni - JavaScript
Функция verni — JavaScript

Пример ВОЗВРАЩЕНИЯ. Мы написали функцию, которая ВОЗВРАЩАЕТ результат перемножения трёх числовых параметров.

verni(2,3,4)
Вызов функции verni - JavaScript
Вызов функции verni — JavaScript

То есть мы передали в функцию, например, числа 2, 3, 4. В ответ функция ВЕРНУЛА значение 24 (тип Number). Что это за числа? Предположим на каком-то этапе алгоритма нам нужно рассчитывать объём помещения, чтобы в дальнейшем правильно рассчитать вентиляционное оборудование. Допустим на каждые 3,27 м3 нужно устанавливать сенсор давления газа. Сколько нужно сенсоров на 24 м3?

var sensors = verni(2,3,4)/3.27
Функция возвращения в алгоритме - JavaScript
Функция возвращения в алгоритме — JavaScript

Итого нужно целых 8 штук сенсоров.

Обратите внимание! Для вычисления количества сенсоров мы не передавали число 24. Наша функция ВЕРНУЛА число 24 после ВЫЗОВА. То есть мы получили совершенно новую единицу информации под конкретную задачу — этой единицы информации не существовало ранее. Мы смогли воспользоваться данными т. к. функция ВЕРНУЛА числовое значение. Это был пример ВОЗВРАЩАЮЩЕЙ функции

 

Функции, которые что-то ДЕЛАЮТ могут не принимать параметров. Такие функции НЕ возвращают ничего. Простой пример. Мы объявим переменную:

var banan = 5

Предположим 5 — это количество бананов в холодильнике. Теперь напишем функцию добавления одного банана в холодильник. Эта функция будет ДЕЛАТЬ — добавлять в холодильник один банан.

function dobavit1 (){
   banan = banan + 1
}

Мы объявили функцию и теперь можем её ВЫЗВАТЬ — СДЕЛАТЬ добавление банана в холодильник

 

Функция dobavit1 - JavaScript
Функция dobavit1 — JavaScript

После того как функция СДЕЛАЕТ, мы увидим в холодильнике 6 бананов. Функция ничего не вернула, она просто изменила другие данные. Эта функция не создала новой единицы информации — она просто модифицировала существующую информацию в переменной.

 

Что ещё?

Функцию можно ОБЪЯВИТЬ в любом месте программы. Хоть с начала, хоть с конца. Интерпретатор первым делом собирает сами функции, а уже потом знает как их выполнять и применяет это в нужных местах.

 

Что такое коллбэк-функция?

Коллбэк-функция — это когда одна функция ПЕРЕДАЁТСЯ в качестве параметра другой функции для дальнейшего взаимодействия. То есть когда нам важна определённая последовательность вызовов разных функций, мы можем ПЕРЕДАВАТЬ её другим функциям для будущих вызовов.

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

  1. Зайти в ванную комнату
  2. Снять штаны
  3. Присесть на унитаз
  4. «Скинуть лишнее»

Как вы думаете? Последовательность этих действий важна? Правильный ответ — важна. Представьте, что порядок выполнения действий нарушится:

  1. Зайти в ванную комнату
  2. Присесть на унитаз
  3. «Скинуть лишнее»
  4. Снять штаны

Вроде всё так же, но во второй последовательности штаны будут испачканы.

 

Смысл коллбэк-функций заключается в строгой последовательности вызовов этих самых функций. Первая передаётся второй, вторая третьей … и т. д.. Результат выполнения одной функции влияет на результат выполнения другой функции.

 


Конструктор Function

Конструктор Function:

  • является %Function%
  • это начальное значение свойства «Function» глобального объекта
  • создает и инициализирует новый объект функции, когда он вызывается как функция, а не как конструктор. Таким образом, вызов функции Function (…) эквивалентен выражению создания объекта new Function (…) с теми же аргументами
  • предназначен для создания подклассов. Он может использоваться как значение предложения extends определения класса. Конструкторы подкласса, которые намереваются наследовать указанное поведение функции, должны включать супервызов super конструктора Function для создания и инициализации экземпляра подкласса с внутренними слотами, необходимыми для поведения встроенной функции. Все синтаксические формы ECMAScript для определения объектов функций создают экземпляры Function. Не существует синтаксических средств для создания экземпляров подклассов Function, за исключением встроенных подклассов GeneratorFunction, AsyncFunction и AsyncGeneratorFunction.

Function ( p1, p2, … , pn, body )

Последний аргумент определяет тело (исполняемый код) функции; любые предыдущие аргументы определяют формальные параметры.

Когда функция Function вызывается с некоторыми аргументами p1, p2, …, pn, body (где n может быть ноль (0), т. е. нет аргументов «p» и где тело также может быть не указано), следующие шаги принято:

1. Пусть C будет активным функциональным объектом.
2. Пусть args будет списком аргументов argumentsList, который был передан этой функции [[Call]] или [[Construct]].
3. Вернуть? CreateDynamicFunction(C, NewTarget, normal, args).

Примечание

Допустимо, но не обязательно иметь один аргумент для каждого формального параметра, который необходимо указать. Например, все три следующих выражения дают одинаковый результат:

new Function(«a», «b», «c», «return a+b+c»)
new Function(«a, b, c», «return a+b+c»)
new Function(«a,b», «c», «return a+b+c»)

var f1 = new Function("a", "b", "c", "return a+b+c")
f1(1,2,3)
Создание функции1 через конструктор - JavaScript
Создание функции1 через конструктор — JavaScript

 

var f2 = new Function("a, b, c", "return a+b+c")
f2(1,2,3)
Создание функции2 через конструктор - JavaScript
Создание функции2 через конструктор — JavaScript

 

var f3 = new Function("a,b", "c", "return a+b+c")
f3(1,2,3)
Создание функции3 через конструктор - JavaScript
Создание функции3 через конструктор — JavaScript

 

CreateDynamicFunction ( constructor, newTarget, kind, args )

Абстрактная операция CreateDynamicFunction принимает аргументы constructor (конструктор), newTarget (конструктор), kind (normal, generator, async или asyncGenerator) и args (Список значений языка ECMAScript).

constructor — это функция-конструктор, выполняющая это действие.

newTarget — это конструктор, к которому изначально был применен new.

args — это значения аргументов, которые были переданы к constructor. При вызове он выполняет следующие шаги:

1. Утверждение: стек контекста выполнения имеет как минимум два элемента.
2. Пусть callerContext будет вторым верхним элементом стека контекста выполнения.
3. Пусть callerRealm будет Realm callerContext.
4. Пусть calleeRealm будет текущей Записью Realm.
5. Выполнить ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
6. Если newTarget не определен — является undefined, установите newTarget на constructor.
7. Если kind является normal, тогда

a. Пусть цель goal будет грамматическим символом FunctionBody [~ Yield, ~ Await] .
b. Пусть parameterGoal будет грамматическим символом FormalParameters [~ Yield, ~ Await] .
c. Пусть fallbackProto будет «%Function.prototype%».

8. Иначе, если kind является generator, тогда

a. Пусть цель goal будет грамматическим символом GeneratorBody.
b. Пусть parameterGoal будет грамматическим символом FormalParameters [~ Yield, ~ Await] .
c. Пусть fallbackProto будет «%GeneratorFunction.prototype%».

9. Иначе, если kind является async, тогда

a. Пусть цель goal будет грамматическим символом AsyncFunctionBody.
b. Пусть parameterGoal будет грамматическим символом FormalParameters [~ Yield, ~ Await] .
c. Пусть fallbackProto будет «%AsyncFunction.prototype%».

10. Иначе,

a. Утверждение: kind является asyncGenerator.
b. Пусть цель goal будет грамматическим символом AsyncGeneratorBody.
c. Пусть parameterGoal будет грамматическим символом FormalParameters [~ Yield, ~ Await] .
d. Пусть fallbackProto будет «%AsyncGeneratorFunction.prototype%».
11. Пусть argCount будет количеством элементов в args.
12. Пусть P будет пустой строкой String.
13. Если argCount = 0, пусть bodyArg будет пустой строкой String.
14. В противном случае, если argCount = 1, пусть bodyArg будет args[0].
15. Иначе,

a. Утверждение: argCount > 1.
b. Пусть firstArg будет args[0].
c. Установить P на ? ToString(firstArg).
d. Пусть k будет равен 1.
e. Повторять, пока k < argCount — 1,

i. Пусть nextArg будет args[k].

ii. Пусть nextArgString будет ? ToString(nextArg).

iii. Установите P на конкатенацию строк P, «,» (запятая) и nextArgString.

iv. Установить k на k + 1.
f. Пусть bodyArg будет args[k].

16. Пусть bodyString будет конкатенацией строк 0x000A (LINE FEED), ? ToString(bodyArg) и 0x000A (LINE FEED).
17. Пусть prefix будет префиксом, связанным с типом kind в таблице 50.
18. Пусть sourceString будет конкатенацией строк префикса prefix, «anonymous («, P, 0x000A (LINE FEED), «) {«, bodyString и «}».
19. Пусть sourceText будет ! StringToCodePoints(sourceString).
20. Выполните следующие подэтапы в порядке, определяемом реализацией, возможно, чередуя синтаксический анализ и обнаружение ошибок:

a.
b.
c.
d.
e.
f.
g.
h.
i.
j.
k.
l.
m.
n.
o.

21.
22.
23.
24.
25.
26.
27.
28.
29.
30.

 

Поделись записью