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

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

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

 

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

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

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

 

Что умеют функции?

Все функции можно поделить на 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. Пусть parameters будет ParseText(! StringToCodePoints(P), parameterGoal).
   b. Если параметры parameters представляют собой Список ошибок, вызовите исключение SyntaxError.
   c. Пусть body будет ParseText(! StringToCodePoints(bodyString), goal).
   d. Если тело body является Списком ошибок, выбросить исключение SyntaxError.
   e. Пусть strict будет FunctionBodyContainsUseStrict из body.
   f. Если strict является true, примените правила ранней ошибки для UniqueFormalParameters : FormalParameters to parameters.
   g. Если strict имеет значение true и IsSimpleParameterList из параметров parameters имеет значение false, генерировать исключение SyntaxError.
   h. Если какой-либо элемент BoundNames из параметров parameters также встречается в LexicallyDeclaredNames из тела body, вызовите исключение SyntaxError.
   i. Если body Содержит SuperCall является true (истинно), выбросить исключение SyntaxError.
   j. Если параметры parameters Contains SuperCall является true (истинно), выбросить исключение SyntaxError.
   k. Если body Contains SuperProperty является true (истинно), выбросить исключение SyntaxError.
   l. Если параметры parameters Contains SuperProperty является true (истинно), выбросить исключение SyntaxError.
   m. Если kind является "generator" или "asyncGenerator", то
      i. Если параметры parameters Contains YieldExpression имеют значение true, генерировать исключение SyntaxError.
   n. Если kind является "async" или "asyncGenerator", то
      i. Если параметры parameters Contains AwaitExpression имеют значение true, генерировать исключение SyntaxError.
   o. Если строго strict является true, то
     i. Если BoundNames из параметров parameters содержит какие-либо повторяющиеся элементы, вызовите исключение SyntaxError.
21. Пусть proto будет ? GetPrototypeFromConstructor(newTarget, fallbackProto).
22. Пусть realmF будет текущей записью Realm Record.
23. Пусть область видимости scope будет realmF.[[GlobalEnv]].
24. Пусть F будет ! OrdinaryFunctionCreate(proto, sourceText, parameters, body, "non-lexical-this", scope).
25. Выполните задание имени функции SetFunctionName(F, "anonymous").
26. Если kind является "generator", тогда
   a. Пусть prototype будет ! OrdinaryObjectCreate(%GeneratorFunction.prototype.prototype%).
   b. Выполнить DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
27. Иначе если kind является "asyncGenerator", тогда
   a. Пусть prototype будет ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
   b. Выполнить DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
28. Иначе если kind является "normal", выполнить MakeConstructor(F).
29. ПРИМЕЧАНИЕ. Функции, у которых kind является "async" не могут быть сконструированы и не имеют внутреннего метода [[Construct]] или свойства "prototype".
30. Вернуть F
Примечание

CreateDynamicFunction определяет свойство «prototype» для любой создаваемой им функции, тип (kind) которой не является асинхронным («async«), чтобы обеспечить возможность использования функции в качестве конструктора.

 

Kind Prefix
normal «function»
generator «function*»
async «async function»
asyncGenerator «async function*»

Таблица 50: Префиксы исходного текста динамической функции

 

Свойства конструктора функций

Конструктор функции:

Function.length

Function.prototype

Function.length

Это свойство данных со значением 1. Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}.

Function.prototype

Значением Function.prototype является объект прототип Function.

 

Свойства объекта-прототипа функции

Объект-прототип функции:

  • является %Function.prototype%.
  • сам по себе является встроенным функциональным объектом.
  • принимает любые аргументы и при вызове возвращает undefined.
  • не имеет внутреннего метода [[Construct]]; его нельзя использовать в качестве конструктора с оператором new.
  • имеет внутренний слот [[Prototype]], значение которого равно %Object.prototype%.
  • не имеет свойства «prototype» .
  • имеет свойство «length«, значение которого равно +0𝔽.
  • имеет свойство «name«, значение которого — пустая строка.
Примечание

Объект прототипа функции указан как объект функции для обеспечения совместимости с кодом ECMAScript, который был создан до спецификации ECMAScript 2015.

 

Function.prototype.apply ( thisArg, argArray )

Когда метод применения apply вызывается с аргументами thisArg и argArray, выполняются следующие шаги:

1. Пусть func будет значением этого this.
2. Если IsCallable(func) имеет значение false, выбросить исключение TypeError.
3. Если argArray является undefined или null, тогда
   a. Выполнить PrepareForTailCall().
   b. Вернуть ? Call(func, thisArg).
4. Пусть argList будет ? CreateListFromArrayLike(argArray).
5. Выполнить PrepareForTailCall().
6. Вернуть ? Call(func, thisArg, argList).
Примечание 1

Значение thisArg передается без изменений как значение this. Это изменение по сравнению с выпуском 3, где undefined или null thisArg заменяется глобальным объектом и ToObject применяется ко всем другим значениям, и этот результат передается как значение this. Несмотря на то, что thisArg передается без изменений, нестрогие функции по-прежнему выполняют эти преобразования при входе в функцию.

 

Примечание 2

Если func является стрелочной функцией или экзотическим объектом связанной функции, то thisArg будет проигнорирован функцией [[Call]] на шаге 6.

 

Function.prototype.bind ( thisArg, …args )

Когда метод привязки bind вызывается с аргументом thisArg и нулем или более аргументов, он выполняет следующие шаги:

1. Пусть Target будет значением этого this.
2. Если IsCallable(Target) является false, выбросить исключение TypeError.
3. Пусть F будет ? BoundFunctionCreate(Target, thisArg, args).
4. Пусть L будет 0.
5. Пусть targetHasLength будет ? HasOwnProperty(Target, "length").
6. Если targetHasLength является true, тогда
   a. Пусть targetLen будет ? Get(Target, "length").
   b. Если Type(targetLen) является Number, тогда
      i. Если targetLen является +∞𝔽, установить L на +∞.
      ii. Иначе если targetLen является -∞𝔽, установить L на 0.
      iii. Иначе,
         1. Пусть targetLenAsInt будет ! ToIntegerOrInfinity(targetLen).
         2. Утверждено: targetLenAsInt является конечным (finite).
         3. Пусть argCount будет количеством элементов в args.
         4. Установить L на max(targetLenAsInt - argCount, 0).
7. Выполнить ! SetFunctionLength(F, L).
8. Пусть targetName будет ? Get(Target, "name").
9. Если Type(targetName) не является String, установить targetName на пустую строку String.
10. Выполнить SetFunctionName(F, targetName, "bound").
11. Вернуть F.

 

Примечание 1

Функциональные объекты, созданные с помощью Function.prototype.bind, являются экзотическими объектами. У них также нет свойства «prototype«.

 

Примечание 2

Если Target является стрелочной функцией или экзотическим объектом связанной функции, то thisArg, переданный этому методу, не будет использоваться при последующих вызовах F.

 

Function.prototype.call ( thisArg, …args )

Когда метод call вызывается с аргументом thisArg и нулем или более аргументов, выполняются следующие шаги:

1. Пусть func будет значением этого this.
2. Если IsCallable(func) является false, выбросить исключение TypeError.
3. Выполнить PrepareForTailCall().
4. Вернуть ? Call(func, thisArg, args).

 

Примечание 1

Значение thisArg передается без изменений как значение this. Это изменение по сравнению с выпуском 3, где undefined или null thisArg заменяется глобальным объектом, а ToObject применяется ко всем другим значениям, и этот результат передается как значение this. Несмотря на то, что thisArg передается без изменений, нестрогие функции по-прежнему выполняют эти преобразования при входе в функцию.

 

Примечание 2

Если func является стрелочной функцией или экзотическим объектом связанной функции, то thisArg будет проигнорирован функцией [[Call]] на шаге 4.

 

Function.prototype.constructor

Начальное значение Function.prototype.constructor — %Function%.

 

Function.prototype.toString ( )

Когда вызывается метод toString, выполняются следующие шаги:

1. Пусть func будет значением этого this.
2. Если func является встроенным функциональным объектом, вернуть определенное реализацией представление исходного кода String для func. Представление должно иметь синтаксис NativeFunction. Кроме того, если у func есть внутренний слот [[InitialName]]и func.[[InitialName]] является строкой String, то часть возвращаемой строки, которой будет соответствовать NativeFunctionAccessoropt PropertyName, должна быть значением func.[[InitialName]].
3. Если Type(func) является объектом Object и func имеет внутренний слот [[SourceText]] и func.[[SourceText]] является последовательностью кодовых точек Unicode и ! HostHasSourceTextAvailable(func) является true (истинно), тогда
   a. Вернуть ! CodePointsToString(func.[[SourceText]]).
4. Если Type(func) является объектом Object и IsCallable(func) является true, вернуть определенное реализацией представление исходного кода String для func. Представление должно иметь синтаксис NativeFunction.
5. Throw a TypeError exception.

NativeFunction :

function NativeFunctionAccessoropt PropertyName[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { [ native code ] }

NativeFunctionAccessor :

get

set

 

Function.prototype [ @@hasInstance ] ( V )

Когда метод @@hasInstance объекта F вызывается со значением V, выполняются следующие шаги:

1. Пусть F будет значением этого this.
2. Вернуть ? OrdinaryHasInstance(F, V).

Значение свойства «name» этой функции — «[Symbol.hasInstance]«.

Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}.

Примечание

Это реализация по умолчанию из @@hasInstance, которую наследует большинство функций. @@hasInstance вызывается оператором instanceof, чтобы определить, является ли значение экземпляром определенного конструктора. Такое выражение, как

v instanceof F

оценивается как

F[@@hasInstance](v)

Конструктор функции может управлять тем, какие объекты распознаются instanceof как её экземпляры, выставляя другой метод @@hasInstance функции.

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

 

Экземпляры функций

Каждый экземпляр функции является функциональным объектом ECMAScript и имеет внутренние слоты, перечисленные в таблице 30. Функциональные объекты, созданные с использованием метода Function.prototype.bind (20.2.3.2), имеют внутренние слоты, перечисленные в таблице 31.

Internal Slot (Внутренний слот) Type (Тип) Description (Описание)
[[Environment]] Environment Record Запись Окружающей Среды о том, что функция была закрыта. Используется как внешняя среда при оценке кода функции.
[[FormalParameters]] Parse Node Корневой узел синтаксического анализа исходного текста, который определяет список формальных параметров функции.
[[ECMAScriptCode]] Parse Node Корневой узел синтаксического анализа исходного текста, определяющий тело функции.
[[ConstructorKind]] base | derived Независимо от того, является ли функция конструктором производного класса.
[[Realm]] Realm Record Область, в которой была создана функция, и которая предоставляет любые внутренние объекты, к которым осуществляется доступ при оценке функции.
[[ScriptOrModule]] Script Record или Module Record Скрипт или модуль, в котором была создана функция.
[[ThisMode]] lexical | strict | global Определяет, как ссылки this интерпретируются в формальных параметрах и теле кода функции. lexical означает, что this относится к значению this как к лексически включающей функции.

strict означает, что значение this используется в точности так, как это предусмотрено при вызове функции.

global означает, что значение this, равное «undefined» или «null«, интерпретируется как ссылка на глобальный объект, а любое другое значение this сначала передается в ToObject.

[[Strict]] Boolean true, если это строгая функция, false, если это нестрогая функция.
[[HomeObject]] Object Если функция использует super, это тот объект, [[GetPrototypeOf]] которого предоставляет объект, с которого начинается поиск свойства super.
[[SourceText]] последовательность кодовых точек Unicode Исходный текст, определяющий функцию.
[[IsClassConstructor]] Boolean Указывает, является ли функция конструктором класса. (Если это правда (true), вызов функции [[Call]] немедленно вызовет исключение TypeError.)

Таблица 30: Внутренние слоты объектов функций ECMAScript

 

Internal Slot (Внутренний слот) Type (Тип) Description (Описание)
[[BoundTargetFunction]] Вызываемый объект Обёрнутый функциональный объект.
[[BoundThis]] Любой Значение, которое всегда передается как значение this при вызове функции-оболочки.
[[BoundArguments]] Список из любых Список значений, элементы которых используются в качестве первых аргументов любого вызова обернутой функции.

Таблица 31: Внутренние слоты связанных функций экзотических объектов

 

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

  • length
  • name
  • prototype

 

length

Значение свойства «length» — это целое число, которое указывает типичное количество аргументов, ожидаемых функцией. Однако язык позволяет вызывать функцию с другим количеством аргументов. Поведение функции при вызове для ряда аргументов, отличных от числа, указанного в ее свойстве «length«, зависит от функции.

Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}.

 

name

Значение свойства «name» — это строка, описывающая функцию. Имя не имеет семантического значения, но обычно представляет собой переменную или имя свойства, которое используется для ссылки на функцию в точке ее определения в коде ECMAScript.

Это свойство имеет атрибуты {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}.

Объекты анонимных функций, которые не имеют контекстного имени, связанного с ними в этой спецификации, используют пустую строку в качестве значения свойства «name«.

 

prototype

Экземпляры функций, которые можно использовать в качестве конструктора, имеют свойство «prototype«. Каждый раз, когда создается такой экземпляр функции, также создается другой обычный объект, который является начальным значением свойства «prototype» функции. Если не указано иное, значение свойства «prototype» используется для инициализации внутреннего слота [[Prototype]] объекта, созданного при вызове этой функции в качестве конструктора.

Это свойство имеет атрибуты {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}.

Примечание

Функциональные объекты, созданные с помощью Function.prototype.bind, или путем оценки MethodDefinition (это не GeneratorMethod или AsyncGeneratorMethod) или ArrowFunction не имеют свойства «prototype«.

 

HostHasSourceTextAvailable ( func )

Определяемая хостом абстрактная операция HostHasSourceTextAvailable принимает аргумент func (объект функции). Это позволяет средам хоста предотвращать предоставление исходного текста для func.

Реализация HostHasSourceTextAvailable должна нормально завершаться во всех случаях. Эта операция должна быть детерминированной по своим параметрам. Каждый раз, когда он вызывается с определенной функцией в качестве аргумента, он должен возвращать одну и ту же запись завершения. Реализация HostHasSourceTextAvailable по умолчанию должна безоговорочно возвращать нормальное завершение со значением true.

 

Из раздела 10.2

Объекты функций ECMAScript инкапсулируют (encapsulate) параметризованный код ECMAScript, закрытый в лексической среде (lexical environment), и поддерживают динамическую оценку этого кода. Функциональный объект ECMAScript является обычным объектом и имеет те же внутренние слоты и те же внутренние методы, что и другие обычные объекты. Код объекта функции ECMAScript может быть кодом строгого режима (strict mode code)(11.2.2) или нестрогим кодом (non-strict code). Функциональный объект ECMAScript, код которого является кодом строгого режима, называется строгой функцией (strict function). Функция, код которой не является кодом строгого режима, называется нестрогой функцией (non-strict function).

В дополнение к [[Extensible]] и [[Prototype]], объекты функций ECMAScript также имеют внутренние слоты, перечисленные в Таблице 30.

Для всех объектов функций ECMAScript здесь определен внутренний метод [[Call]]. Функции ECMAScript, которые также являются конструкторами, дополнительно имеют внутренний метод [[Construct]].

 

Из раздела 10.2.2

Когда контекст выполнения (execution context) устанавливается для оценки функции ECMAScript, создается новая запись среды функции (function Environment Record), и в этой записи среды (Environment Record) создаются привязки для каждого формального параметра. Также создается каждое объявление в теле функции. Если формальные параметры функции не включают инициализаторы значений по умолчанию, тогда объявления тела создаются в той же записи среды (Environment Record), что и параметры. Если существуют инициализаторы параметров значения по умолчанию, для объявлений тела создается вторая запись среды (Environment Record). Формальные параметры и функции инициализируются как часть FunctionDeclarationInstantiation. Все остальные привязки инициализируются во время оценки тела функции.

ЗАМЕТКА 2

B.3.3 предоставляет расширение для вышеуказанного алгоритма, которое необходимо для обратной совместимости с реализациями ECMAScript в веб-браузерах, предшествующими ECMAScript 2015.

ЗАМЕТКА 3
Инициализаторы параметров могут содержать прямые выражения eval. Любые объявления таких значений верхнего уровня видны только коду eval (11.2). Создание среды для таких объявлений описано в 8.5.3.

 

Из раздела 10.3

Объекты встроенных функций, определенные в этой спецификации, могут быть реализованы либо как объекты функций ECMAScript (10.2), поведение которых обеспечивается с использованием кода ECMAScript, либо как экзотические объекты функций, обеспечиваемые реализацией, поведение которых обеспечивается каким-либо другим способом. В любом случае эффект от вызова таких функций должен соответствовать их спецификациям. Реализация также может предоставлять дополнительные встроенные функциональные объекты, которые не определены в этой спецификации.

Если встроенный функциональный объект реализован как экзотический объект, он должен иметь поведение обычного объекта, указанное в 10.1. Все такие экзотические объекты функций также имеют внутренние слоты [[Prototype]], [[Extensible]] и [[Realm]].

Если не указано иное, каждый встроенный объект функции имеет объект %Function.prototype% в качестве начального значения его внутреннего слота [[Prototype]].

Поведение, указанное для каждой встроенной функции с помощью шагов алгоритма или других средств, является спецификацией поведения тела функции для обоих вызовов функции [[Call]] и [[Construct]]. Однако вызов [[Construct]] поддерживается не всеми встроенными функциями. Для каждой встроенной функции при вызове с помощью [[Call]] [[Call]] thisArgument предоставляет значение this, [[Call]] argumentsList предоставляет именованные параметры, а значение NewTarget не определено — является undefined. При вызове с помощью [[Construct]] значение this не инициализируется, список аргументов argumentsList [[Construct]] предоставляет именованные параметры, а параметр [[Construct]] newTarget предоставляет значение NewTarget. Если встроенная функция реализована как объект функции ECMAScript, то это указанное поведение должно быть реализовано кодом ECMAScript, который является телом функции. Встроенные функции, которые являются объектами функций ECMAScript, должны быть строгими функциями. Если встроенный конструктор имеет какое-либо поведение [[Call]], кроме генерирования исключения TypeError, реализация функции ECMAScript должна выполняться таким образом, чтобы внутренний слот функции [[IsClassConstructor]] не имел значения истины true.

 

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

Стандарт ECMAScript — Раздел «10.2 ECMAScript Function Objects» — https://tc39.es/ecma262/#sec-ecmascript-function-objects

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