“this” in JS exercise

📄 Table of contents

  • “this” exercise
  • ‘this’ inside arrow functions
  • this’ in a function nested inside a method of an object
  • “this” inside classes

▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ ✦ ✦ ✦ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬

◉ “this” keyword in js

The JavaScript this keyword refers to the object it belongs to.

It has different values depending on where it is used:

  • In a method, this refers to the owner object.
  • Alone, this refers to the global object.
  • In a function, this refers to the global object.
  • In a function, in strict mode, this is undefined.
  • In an event, this refers to the element that received the event.
  • Methods like call(), and apply() can refer this to any object.

Note that I’m calling the walk method in this case, which is inside of the object.

But when we apply some slight changes, different results were obtained. Lets say, now we added another const named as newWalk which gives reference to the walk method in the user object. For simplicity, we can say newWalk is a function that calls the walk method in the user object.

This time we if we call the newWalk method by giving a reference to another method (walk) then most likely you will obtain undefined on the console. (Note that in my case we obtained a window object as I’m running this code in a React Project with Strict Mode disabled).

◉ bind-ing “this"

In JavaScript, we can use the bind method to fix the problem that we discussed in the above section, as we aren’t able to access the user object in both cases. Using the bind method you can simply bind an object to a function.

For example,

  • In the previous example where we aren’t able to access the user object using the this keyword, using the bind method you can solve all of that issues quickly.
  • We just have to pass .bind(an object that you want to give reference) to your function & we longer have to work with an undefined or window object, because the this keyword now always give reference the user object

◉ “this” exercises

var foo = {
name: "anil",
age: 30
};
function getDetails() {
return (this.name + " is + this.age + " yrs old.");
}
foo.logMyDetails = getDetails;
console.log(foo.logMyDetails());
//anil is 30 yrs old.
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
function Employee(name) {
this.name = name;
this.getName = function () {
return this.name;
}
}
var e1 = new Employee(“anil");
e1.getName();
#anil ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
function Employee(name) {
this.name = name;
}
Employee.getName = function () {
return this.name;
}
var e2 = new Employee("kumar");
e2.getName(); #TypeError
var e3 = e2.getName;
console.log(e3()); #TypeError
var e4 = e2.getName.bind(e2);
console.log(e4()); #TypeError
NOTE: if we re-write above getName as `Employee.prototype.getName` then above bind() will work and print "kumar" accordingly.▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬var x = "outermost";
var foo = {
x: "inner",
baz: {
x: "innermost",
bar: function () {
return this.x;
}
}
}
var go = foo.baz.bar; # "this" refers to global object
console.log(go());
console.log(foo.baz.bar())# outermost
# innermost

◉ ‘this’ inside arrow functions

source: https://medium.com/javascript-in-plain-english/the-this-keyword-in-javascript-for-generic-and-arrow-functions-a-detailed-guide-5be2070184bf

The way ‘this’ works in arrow functions is different from generic functions. The arrow functions pick up the same context as that of the enclosing function. The ‘this’ keyword thus points to the context of the enclosing function. Consider the following example

The enclosing function for the arrow function ‘a’ is foo() and the context of the foo() function is the global object. Thus the ‘this’ keyword points out the global object here. Now consider the below example

The ‘this’ keyword of the function doo() points to the object ‘a’ since the enclosing function foo() is implicitly bounded to object ‘a’ and hence the doo() function picks up the context of foo().

Consider the below example for explicit binding and it should be pretty straightforward to guess the output.

Here too the ‘this’ of the doo function points to the object ‘a’ since the enclosing function foo is bound to object ‘a’ explicitly.

Exercises for the brave

Exercise 1:

Explanation

First, at line 13 the function func() is implicitly bound to myObject and hence ‘this’ refers to myObject. At line 4 we save the myObject in variable self. The console.log statements at line 5 and line 6 will read as below because of the implicit binding

  • “outer func: this.foo = bar”
  • “outer func: self.foo = bar”

In line 7 we have an immediately invoked function expression (IIFE) and since this function is not bound to any object (implicitly or explicitly) ‘this’ will point to a global object hence this.foo is undefined as foo is not a vriable present on the global object. Thus the output for line 8 and line 9 is as follows

  • “inner func: this.foo = undefined”
  • “inner func: self.foo = bar”

Here self stores myObject as previously discussed and is accessible to IIFE because of closure in JS ( more about it here ). Thus self.foo is equal to “bar”.

Exercise 2:

Since arrow functions pick up the context of the enclosing function (func() here) ‘this’ and ‘self’ both point out to myObject and hence the output is as follows :

  • “outer func: this.foo = bar”
  • “outer func: self.foo = bar”
  • “inner func: this.foo = bar”
  • “inner func: self.foo = bar”

◉ What happens to ‘this’ in a function nested inside a method of an object?

It is essential to understand how function invocations and method invocations differ because in each of these invocations, the value of this is different. Let’s see below examples of function invocations below:

Explanation: splitName() is a REGULAR function inside setName() but not directly bind to profile object. So, it sets “this” to `window` object, which doesn’t have a firstname property, , and hence the NaN outputs are obtained.

How do we solve this issue?

[1]. One solution is to assign the this value from the outer function to a variable to be used in the nested function like so:

var self = this;

[2]. Second solution to this problem involve using bind(), call() or apply().

[3]. Thirdly, converting it to fat arrow function, splitName=()=> function looses its “this” and gets value of this from enclosing body which is profile over here.

Explanation:

this.value refers to the value property in the ‘object’ object.

And add method has a parameter called val and number functions takes that as a parameter and return val * this.value, but this.value in the number functions is undefined and 10 * undefined is equal to NaN. So, the answer is 20 , NaN.

Output : 5,NaN, 5

◉ `this` inside Classes

--

--

--

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Configure Lint-Staged with Create React App, TypeScript, Eslint, Prettier, Husky

Ranking of the best front-end frameworks in 2019

Frontend Web-app battles — Tech predictions for 2017 #tech2017

JavaScript Increment and Decrement operators

Find Callbacks Confusing? They are Nothing But…

Why REACT Is The Best?

React Function Components vs Class Components

Get Started with Headless Web

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store

Anil Kumar

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

More from Medium

LEARN HOW TO USE GETTERS AND SETTERS IN JAVASCRIPT

Uploading a Node.js app on Cpanel using Namecheap

Partials in Handlebars Express.js and using a Middleware

BigBasket clone using pure HTML, CSS & JS