03. Function Invocation
In JavaScript, this
is the current execution context of a function. JS has 5 function invocation types:
Function invocation:
alert('Hello World!')
Method invocation:
console.log('Hello World!')
Arrow function invocation.
Constructor invocation:
new RegExp('\\d')
Indirect invocation:
alert.call(undefined, 'Hello World!')
and each one defines its own context, this behaves slight different than developer expects.
Before starting, let's familiarize with a couple of terms:
Invocation is executing the code that makes the body of a function (simply calling the function). For example
parseInt
function invocation isparseInt('15')
.Context of an invocation is the value of
this
within function body.Scope of a function is a set of variables, objects, functions accessible within a function body.
Function Invocation
In function invocation this
is the global object. The global object is determined by the execution environment.
It is the
window
object in a web browser.It is the
global
object in a node environment.this
isundefined
in a function invocation in strict mode. The strict mode is active not only in the current scope, but also in the inner scopes (for all functions declared inside).
A common trap with the function invocation is thinking that this is the same in an inner function as in the outer function. Correctly the context of the inner function depends only on invocation, but not on the outer function's context. To have the expected this
, modify the inner function's context with indirect invocation (using .call()
or .apply()
) or create a bound function (using .bind()
).
this для вложенной функции определяется самой этой функцией, только если она не стрелочная.
Method Invocation
Method invocation is performed when in a form of property accessor that evaluates to a function object. this
is the object that owns the method in a method invocation.
A method from an object can be extracted into a separated variable. When calling the method using this variable, you might think that this is the object on which the method was defined. Correctly if the method is called without an object, then a function invocation happens: where this is the global object window
or undefined
in strict mode. Creating a bound function (using .bind()
) fixes the context, making it the object that owns the method.
Arrow function Invocation
Arrow-функции не имеют собственного this
и оно для их определяется по правилам лексической области видимости. Простыми словами, Arrow функции заимствуют this
из окружающей их области видимости.
Constructor Invocation
Constructor invocation is performed when new
keyword is followed by an expression that evaluates to a function object. When a property accessor myObject.myFunction
is preceded by new
keyword, JavaScript will execute a constructor invocation, but not a method invocation.
In a constructor invocation this
is the newly created object:
Using a function invocation to create objects is a potential problem (excluding factory pattern), because some constructors may omit the logic to initialize the object when new
keyword is missing.
Indirect Invocation
Indirect invocation is performed when a function is called using .call()
or .apply()
methods. this
is the first argument of .call()
or .apply()
in an indirect invocation
The method
.call(thisArg, arg1, arg2, ...)
accepts the first argumentthisArg
as the context of the invocation and a list of argumentsarg1, arg2, ...
that are passed as arguments to the called function.The method
.apply(thisArg, [arg1, arg2, ...])
accepts the first argumentthisArg
as the context of the invocation and an array-like object of values[arg1, arg2, ...]
that are passed as arguments to the called function.
The spread operator (
...
) mostly replacesapply()
.
this
propagation
this
propagationСуществует проблема, когда функция-callback, вызванная внутри другой функции имеет свой собственный this
, который равен или глобальному объекту, или undefined
(в строгом режиме).
В следующем примере this.name
внутри функции выдаст ошибку, поскольку внутри анонимной функции this = undefined
.
Существует четыре способа решения этой проблемы:
Введение дополнительной временной переменной:
Использование
bind
для явного заданияthis
:
Передача
this
параметра в функциюforEach
:
Использование arrow-functions в качестве функции обратного вызова (рекомендуемый):
Activation Object
При вызове функции создается объект активации, остающийся для вас невидимым. Это скрытая структура данных, которая содержит информацию и связывает все то, что функция должна выполнить, а также содержит обратный адрес активации вызывающей функции.
В языках, подобных C, объекты активации размещаются в стеке. Они покидают стек (или выводятся из него), когда функция возвращает управление. В JavaScript происходит иначе. Объекты активации JavaScript размещает в куче, как обычные объекты. При возвращении функцией управления объекты активации не проходят автоматическую деактивацию. Вместо этого объект активации может выживать, пока на него есть ссылка. Объекты активации подпадают под сборку мусора, как и обычные объекты.
В объекте активации содержатся:
ссылка на функциональный объект;
ссылка на объект активации вызывающей функции. Она используется инструкцией
return
для возврата управления;информация о возвращении, которая применяется для продолжения вы- полнения кода после вызова. Обычно это адрес инструкции, выполняемой сразу же после вызова функции;
параметры функции, инициализированные аргументами;
переменные функции, инициализированные значением
undefined
;временные переменные, используемые функциями для вычисления сложных выражений;
содержимое
this
, которое может быть ссылкой на интересующий объект, если функциональный объект был вызван как метод.
В функциональном объекте содержатся также два скрытых свойства:
ссылка на исполняемый код функции;
ссылка на объект активации, который был активен в момент создания функ- ционального объекта. Это делает возможным создание замыкания. Функция может использовать это скрытое свойство для доступа к переменным той функции, которая ее создала.
Last updated
Was this helpful?