Introduction

Developers use one of these two mechanisms:
- lexical range of visibility
- “this mechanism”
The mechanism using the “this” keyword provides an elegant way to implicitly “pass” a reference to a particular object, resulting in a cleaner design and easier code reuse. Developers who avoid using this mechanism mostly do so because they don’t understand the principles of how that mechanism works.
“This” is not a variable but a special programming language word (operator) and represents a link that points to some reference (object). It is activated, i.e. gains meaning only at the moment when the function that contains it is called (invoke).
It does not depend on where the function is declared, but solely on where and how the function is called!
Rules for determining the meaning of “this”
The whole process of determining the meaning is based on recognizing “who” and how it calls the function containing “this”. The sequence of actions is as follows:
- First it is checked whether the constructor function is called with operator new(). If it is called in this way, then the value “this” is explained under the point a) Calling the function with the operator “new” but if it is not called in this way, then it is done…
- … control whether the function is called with the help of call(), apply() (or bind) methods. If it is called in this way, then the value of “this” is explained under point b) Calling with call(), apply() or bind(), but if it is not called in this way, then it is done …
- …check if the function is called as a method of the object. If it is called in this way, then the value “this” is explained under the point c) Calling the method of the object, but if it is not called in this way, then it is…
- …default linking, which is explained under d) Default linking
If by any chance several different rules are used, priority is applied according to the order from the previously described procedure.
a) Calling the function with the “new” operator
After calling the constructor function with the new operator, this inside the constructor function points to an object instance.
|
1 2 3 4 5 6 |
function Osoba(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } var pera = new Osoba("Pera","Peric"); pera.lastName; // Returns"Peric" |
b) Calling with call(), apply() or bind()

In JavaScript, functions are objects, in the language itself there are predefined methods for them and they can be used on any function. The built-in methods that can change the object pointed to by the this operator are: apply(), call() and bind(). The main difference between the bind() method and the apply()/call() method is that the apply()/call() methods immediately call (eng. invoke) the function, while the bind() method does not, so it is necessary to additionally call the function. In the following example it isshown “binding” this in a function defined outside the object using bind(), to the desired object.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const myCar = { brand: 'Ford', type: 'Sedan', color: 'Red' }; // A function that is not an object method const getColor = function() { console.log(this.color); }; // Try calling the function getColor(); // Returns: undefined // Binding a function to an object with bind() getColor.bind(myCar)(); // Red |
In the call() and apply() methods, the first argument defines which object this will point to, while the other arguments pass the parameters needed by the basic function. The only difference between the apply() and call() methods is the way the method accepts the arguments passed to the base function. The call() method adds other arguments with a comma, while the apply() method adds other elements as an array of elements.
|
1 2 |
someFunction.call(objekatNaKojiUkazujeThis, drugiArgument, treciArgument...) someFunction.apply(objekatNaKojiUkazujeThis, [drugiArgument, treciArgument...]) |
TIP:
To make it easier to remember in which form each method accepts arguments, use the first letters of the method:
Apply <=> Array or Call <=> Comma.
c) Calling the object method
When a function is inside an object, then when calling the object’s method, the this keyword points to that object (which is the “owner” of the method).
|
1 2 3 4 5 6 7 8 |
var person = { firstName:"Pera", lastName: "Peric", vratiThis: function () { return this; } } person.vratiThis();// Returns: Object {firstName: "Pera", lastName: "Peric"} |
Since this points to the person object, we can use it from the method to call the properties of the object:
|
1 2 3 4 5 6 7 8 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { return this.firstName + " " + this.lastName; } } person.fullName(); // ReturnsPera Peric |
Example
|
1 2 3 4 5 6 7 8 9 |
function foo (){ console.log(this.a); } spoljniObjekat = { a: 2, foo:foo }; spoljniObjekat.foo(); // Output: 2 |
In the previous example, the foo() function is not directly owned by the “externalObject” object, but the object property has an external reference to that function. For determining the objects pointed to by the operator this, the place of calling the function that engages this is important, so in this case, since the function is called from the object “externalObject”, it behaves like a method of the object, so this points to the object!
Example
The following example shows that only the “closest” (“last”) object in the expression for calling the function is important, i.e. that the this operator points to it.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function foo (){ console.log(this.a); } spoljniObjekat = { a: 2, foo:foo }; najveciObjekat = { a: 33, spoljniObjekat: spoljniObjekat }; najveciObjekat.spoljniObjekat.foo(); // Output: 2 |
d) Default behavior
The default behavior is used when no other rule applies. When this rule applies this points to the global object (window).
Example
In the following example, the function foo() is called from the global context and not as an object method, so this points to a global object:
|
1 2 3 4 |
function foo (){ console.log(this); } foo() // Output: Window object |
Most often, the programmer does not want the this special word to point to a global object, but if the default linking rule is applied anyway (most often due to an inadvertent programming error), the compiler will not throw any error! Therefore, it is recommended to turn on strict mode because in that case the compiler throws an “undefined” error for every reference to a global object, so the programmer can spot the error in time.
Example
So the same example as the previous one but with strict mode on it returns undefined
|
1 2 3 4 5 |
function foo() { 'use strict'; console.log(this); } foo(); // Output: undefined |
Problems with “this” and their solutions
Through the following examples, I will try to explain the cases when the behavior of the word this is confusing, ie. when this does not behave as we expect at first sight. From the point of view of “this”, it only matters from where the function containing the this operator is called.
Problematic cases
a) “This” inside the closure
Problem occurring with clousure‘s function is that although they are inside the object, they do not have access to the object through their this operator (because it points to a global object). The Closure function is called by another function and not an object, so the “default rule” is used.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { var spajanjeImena = function(){ console.log(this.firstName + " " + this.lastName); }; return spajanjeImena(); } }; person.fullName(); // Returnsundefined undefined |
In this example, the method person.fullName() is called, which calls the function mergeName(). Since the function concatenateNames() is not called from the object (it was called by another function) the “default rule” is used. Therefore, calling the fullName() method returns undefined, because this points to the global object window, and the global object window does not have window.name and window.surname properties.
Solution
The best solution to this problem is with the help of the bind() method, which binds “this” function mergeName() to “this” function fullName(). After that, since this of the fullName() method points to the “person” object, so our this internal function will also point to the “person” object.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { var spajanjeImena = function(){ console.log(this.firstName + " " + this.lastName); }.bind(this); // add a bind() method return spajanjeImena(); } }; person.fullName(); // Pera Perić |
In addition to this method, we can solve the problem using the “self=this” mechanism or the arrow function because the “parent” function has access to the object (through its “this”).
b) “This” inside setTimeout()
The setTimeout() function calls the callback function after some time interval (which means the function was called from another function, not an object). Therefore, the “default behavior” applies, so this points to a global object. In the following example, this points to a global object:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var a = "Global variable" function OsnovniObjekat (){ this.a = "Internal variable"; console.log("Van setTimeout zovemo " + this.a) this.b = setTimeout(function(){ console.log("Iz setTimeout zovemo " + this.a); }, 1000); } var noviObjekat = new OsnovniObjekat(); // "Outside setTimeout we call Internal variable" // "From setTimeout we call the Global variable" |
This constructor can be written differently by extracting the callback function as a new property of the prototype object, and then we can call it with this.callback:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var a = "Global variable" function OsnovniObjekat (){ this.a = "Internal variable"; this.b = setTimeout(this.callbackFunkcija, 1000); } OsnovniObjekat.prototype.callbackFunkcija = function(){ console.log(this.a); } var noviObjekat = new OsnovniObjekat(); // Returns: A global variable |
This problem is solved by using the bind() method. It is necessary to bind “this” inside the callback function to each newly created object. Therefore, the parameter of the bind() method should be the object that we want “this” to point to, which in this case is again “this” (after using the “new” operator, “this” points to the newly created object)
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var a = "Global variable" function OsnovniObjekat (){ this.a = "Internal variable"; this.b = setTimeout(this.callbackFunkcija.bind(this), 1000); } OsnovniObjekat.prototype.callbackFunkcija = function(){ console.log(this.a); } var noviObjekat = new OsnovniObjekat(); // Returns: Internal variable |
c) “This” in the so-called “extracted method”
A method is just a property of an object that has a reference to some function. When we assign an object method to a variable, we have assigned a function reference to the variable. Therefore, it should be understood that by calling that variable we are not calling a method of the object but an ordinary function.
Example
|
1 2 3 4 5 6 7 8 9 10 11 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { return this.firstName + " " + this.lastName; } } person.fullName(); // Returns: Pera Perić var prikazPunogImena = person.fullName // we assign the variable a reference to the function prikazPunogImena(); // Returns: undefined undefined |
The preceding example from the this viewpoint looks like this:
|
1 2 3 4 |
var prikazPunogImena = function () { return this.firstName + " " + this.lastName; } prikazPunogImena(); |
From the attachment it can be seen that the function displayFullName() is called, not the method of the object. Therefore, the “default rule” is used when this points to a global window object that has no window.name and window.surname properties and returns undefined, undefined.
Problem solution
This problem is solved with the bind() method, with which we will explicitly bind this from the function to the “person” object, after which it no longer matters from where the function is called.
|
1 2 3 4 5 6 7 8 9 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { return this.firstName + " " + this.lastName; } } var prikazPunogImena = person.fullName.bind(person) // Binding "this" to the "person" object prikazPunogImena(); // Returns: Pera Peric |
d) “This” inside the Event handler
This inside the “inline” event handler
One ofthe biggest drawback of this outdated way of registering events is that this points to a global object.
|
1 2 3 4 5 6 7 |
<p><a id="link" href="#" onclick="EventHandler();">click me</a></p> <script> function EventHandler() { console.log(this); // Returns: A global object } </script> |
“This” within the traditional event handler and the W3C model
In traditional event registration, this indicates the element that was the trigger for the event.
|
1 2 3 4 5 6 7 8 9 10 |
<p><a id="link" href="#">click me</a></p> <script> var link = document.getElementById("link"); link.onclick = EventHandler; function EventHandler() { console.log(this.id); // Returns: "link" } </script> |
“This” within the W3C event handler model
In the W3C model with addEventListener() this indicates the element that was the trigger for the event.
|
1 2 3 4 5 6 7 8 9 |
<button id="dugme" type="button">Klikni me</button> <script> var el = document.getElementById("dugme"); el.addEventListener("click", myFunction); function myFunction (){ console.log(this.id); // Returns: "dugme" } </script> |
Troubleshooting Procedures
If “this” doesn’t point to what we want, there are ways we can change the meaning of the “this” keyword.
a) bind(), call(), apply()
One way to predefine the meaning of “this” is to use one of the methods: bind(), call(), apply(). All three methods, through an argument, define an object to which this from the function should be “attached”. Therefore, when calling the method, it is enough to add one of the mentioned methods:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const myCar = { brand: 'Ford', type: 'Sedan', color: 'Red' }; // A function that is not an object method const getColor = function() { console.log(this.color); }; // Binding a function to an object with bind() getColor.bind(myCar)(); // Red |
b) Arrow function
With the new version of JavaScript ECMAScript 6 comes a new way of writing the arrow function. Arrow function instead of applying one of the 4 standard rules for binding this, it completely bypasses the standard mechanism and binds this to the surrounding scope of visibility (lexical scope of visibility). When calling these functions, this inherits the meaning of this from the surrounding function. Simplified this arrow function equates to what this would point to from the external function surrounding the arrow function (it has a built-in engine that practically replaces the known mechanism: “self=this”). When using the arrow function it doesn’t matter how and where the function is called, only what this from the external function points to.
The meaning given to the this operator inside the arrow function cannot be changed later! So it cannot be overridden with the predefined bind(), apply() or call() methods or even with the “new” operator.
Example (closure)
The already mentioned problem from the transition part can also be solved using the arrow function:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { var spajanjeImena = function(){ console.log(this.firstName + " " + this.lastName); }; return spajanjeImena(); } }; person.fullName(); // Returnsundefined |
Solution
Since the arrow function is used, it inherits the meaning of this from the surrounding function that “wraps” the arrow function. In this case, the surrounding function is fullName(), so this inside the arrow function will point to the same as the fullName() function, i.e. this will point to the object “person”.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { console.log(this); // this function fullName() points to a "person" object var spajanjeImena = () => { console.log(this.firstName + " " + this.lastName); }; return spajanjeImena(); } }; person.fullName(); // Pera Perić |
c) “self=this” mechanism
This mechanism actually does not use the this operator, but instead bypasses its application. The problem that occurs with closure functions is that although they are inside the object, they do not have access to the object through their this operator (because it points to a global object). However, its “parent” function has access to the object, through its “this” operator, and we will use that to solve the problem.
If we store a reference to the object (pointed to by the outer function’s “this”) within a new variable (e.g.“self”), we will allow the inner function (closure) to access the objectvia that new variable “self”.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
var person = { firstName:"Pera", lastName: "Peric", fullName: function () { var self = this // let's remember what this points to in the self variable var spajanjeImena = function(){ console.log(self.firstName + " " + self.lastName); }; return spajanjeImena(); } }; person.fullName(); // Pera Perić |
