We shall spend much of the article learning about
this and Functions
The value that
this‘s value will change depending on how that function is defined, how it is invoked and the default execution context.
this always holds the reference to a single object, that defines the current line of code’s execution context.
Before we delve further into how
this behaves in functions, let us look at how it behaves outside them:
A line of code written outside a function is said to belong to the global context and the value of
this in this global context is the same as the global object.
For example, if you opened up your browser console and typed the following lines into it, and press return/enter:
You would see the Window object being logged into the console.This is because the global object, in a browser run-time such as Chrome’s run-time, is the Window object.
Inside a function, however, the global context might no longer be present and the function may have its own defined context and therefore a different value of
this. To understand that, let us turn our attention back to functions :
this with function invocation:
this inside the doSomething function, if it is invoked through the function invocation as above, has the value of the global object, which is the window object in the browser environment:
However, this is not always the case. If the
doSomething() function were running in
strict mode, it would log
undefined instead of the global window object.This is because, in strict mode(indicated by the line :
'use strict';), the default value of this, for any function object is set to undefined instead of the global object.
For example :
this with method invocation:
Functions, when defined as fields or properties of objects, are referred to as methods.
John is 31 years old
In the above code example,
logInfo() is a method of the
person object and we invoked it using the object invocation pattern.
That is, we used the property accessors to access the method which was part of the object.
Such an invocation requires the use of an expression that evaluates to the object which our method is a part of, and a property accessor(Eg :
person.logInfo()) followed by a set of opening and closing parentheses.
It is essential to understand how
function invocations and
method invocations differ.
This in turn will help us understand what the
this context might be in any given function, because in each of these invocations, the value of
this is different.
Inside such a method, that has been invoked using the property accessors,
this will have the value of the invoking object, that is
this will point to the object that was used in conjunction with the property accessor to make the call.
For example :
[object Object] 1 [object Object] 2
In the above example,
calc() is a method of the
add object and is therefore called using the method invocation rules in lines 9 and 10.
And we know, when method invocation patterns are used, the value of
this is set to the calling object.
calc() method, the value of this is set to the calling object, which in our case is
add. and thus we can successfully access
However, let us know look at one major confusion point:
What happens to
this in a function nested inside a method of an object?
[object Object] [object Window] NaN [object Object] [object Window] NaN
Let’s try to understand what just happened.
When we call
calc() in lines 14 and 15 we are using method invocation which sets
calc(). This can be verified using the log statement in line 4.
innerfunc() is called from within the
calc() method using a simple function invocation(line 11 ). This means, inside
this is set to the global object, which does not have a
num property, and hence the NaN outputs are obtained.
How do we solve this issue?How can we retain the value of
this from the outer method inside the nested function?
One solution is to assign the
this value from the outer function to a variable to be used in the nested function like so:
[object Object] [object Object] 1 [object Object] [object Object] 2
Other solutions to this problem involve using
bind(), call() or apply(), which we will soon look into.
this with constructor invocation:
Constructor invocation is performed when
new keyword is followed by an function name, and a set of opening and closing parentheses(with or without arguments).
For example: let person1= new People(‘John’, 21);
person1 is the newly created object and
People is the constructor function used to create this object.
What exactly happens when we use the
new keyword is conjunction with a function name?
There are essentially five steps involved in creating a object through this method.Let use study them with the following example:
John is 21 years old
- Firstly, an empty object is created that is an
instance ofthe function name used with
people(name, age)). In other words, it sets the
constructorproperty of the object to the function used in the invocation(
- Then, it links the prototype of the constructor function(
people) to the newly created object, thus ensuring that that this object can inherit all properties and methods of the constructor function
- Then, the constructor function is called on this newly created object.If we recall the method invocation, we will see that is similar.Thus, inside the constructor function,
thisgets the value of the newly created object used in the call.
- Finally, the created object, with all its properties and methods set, is returned to
One should remember that the
newkeyword is essential for correctly setting the context inside the constructor function.Without
newwe would have a normal function invocation and hence
thismight be incorrectly set to the global object even inside the constructor.