Understanding ‘this’

Amogh Palnitkar
Maverick Labs
3 min readOct 17, 2017

--

Context in JavaScript has never been straight forward to understand. For a guy like me, who was familiar with Java before JavaScript, understanding ‘this’ was even more disconcerting. this in Java simply refers to the current instance of the object. On the other hand, ‘this’ in javascript has ifs and buts all over the place.

Context vs Scope

First things first, let us clear out any confusion between context and scope. I have come across innumerable articles where scope and context are used interchangeably. Simply put scope refers to visibility of variables and context refers to the object within which functions are executed. Context is always refers to the value of this.

var foo = function() { 
var bar = 20;
}
var w1 = this;
console.log(foo); //function(){var var = 20;}
console.log(bar); //undefined. because the bar is out of'scope'
console.log(w1); //window. refers to 'context'

Global Context

Global execution will evaluate this to the current window in case of a browser.

var foo = this;console.log(foo === window) //true

Functional Context

Functional context is where the confusion begins. There are innumerable stackoverflow questions where novice JS programmers complain that, the value of this tends to change unpredictably. Let us make this predictable by taking look at few examples.

Example 1

//variable declared in global context
var foo = 1;
var w1 = this;
//all functions declared in global contextfunction f1(){
return this;
}
function f2(){
return this.foo;
}
function f3(){
return window.foo;
}
console.log(f1() === window) //true
console.log(f2()) //value is 1
console.log(f3()) //value is 1
console.log(w1 === window) //true

In example 1, all the functions are called in the global context. Therefore, the value of this is ‘window’ in each of the functions.

Example 2

Using this in an inner function

var f1 = {
x: function () {
return this;
}
}
var w1 = this;console.log(f1.x() === f1) //true
console.log(f1.x() === window) //false
console.log(w1 === window) //true

As you can see from the above example, value of this inside x is no longer window, but is set to the object the method is called on. ( In our example, f1 is the object, method, x is called on ). To make matters clear, w1 still evalutes to window.

We can extend the above example by nesting one more object inside f1. Below example should help you understand the behavoir.

var f1 = {
f2 : {
x : function(){return this;}
}
}
var w1 = this;console.log(f1.f2.x() === f2) //true
console.log(f1.f2.x() === f1) //false
console.log(w1 === window) //true

For the sake of simplicity, I am skipping ‘use strict’ here. But keep in mind that using strict changes the rules of this.

Example 3

Imagine this to be liquid if you may, in the sense, it takes the form of it’s container.

var f1 = {
x : function(){return this;}
}
var f2 = {
y : f1.x
}
console.log(f1.x() === f1) //true
console.log(f2.y() === f1) //false
console.log(f2.y() === f2) //true

Example 4

Introducing new. New manifests java-like behavior, wherein it creates instances of the object. It would be straightforward to understand for Java developers.

var Person = {
this.name = "John";
}
var p1 = new Person();
var w1 = this;
console.log(p1.name === "John") //true
console.log(w1 === window) //true

To summarize, value of this depends on the context of the execution. It takes the form of it’s container if referenced dynamically and, creating instances using new gives it a java-like meaning.

To execute any function in any desired context, we use functions like call, bind and apply which will be covered in the following articles.

Thanks for reading this article. If you have liked the article, be sure to hit the clap button.

For more such articles, follow Maverick Labs on Medium. We build apps for Android, iOS and Web and we like to share our experience with the community.

You can also connect with us on Our Website, Github & Facebook

--

--