How this Works in JavaScript

Vinay Kumar
Webtips
Published in
5 min readJul 2, 2020

One of the most weird concepts of javascript is where this keyword is referencing to. Every function receives two addition parameters excluding declared parameter: this and arguments. The this keyword is very important in javascript and let's see what it is.

Every function while executing has a reference to its current execution context called “ this". Here execution refers to where the function is getting called and when it will be called. There are four rules for how "this" keyword gets bind. It tells how "this" keyword will get bind for functions. Let's see what are those.

1. Function Binding

Let's take an example and see how “this” gets bind.

We are trying to log the name which is present in person(). In the non-strict mode it will default " this" keyword to global object and in the strict mode it will default to undefined. If the strict mode is applied within the person() then this.name will throw an error so it's not mandatory that always it should be applied at the program level. The same will happen in the case of IIFE as well.

'use strict'; var name = 'Micheal'; (function() { console.log(this.name); //this.name throws an error. })();

2. Method binding

When a function is stored as a property of an object it is called a method. When a method is invoked “ this" is bound to the object(left of the dot). Let's consider an person() example again.

We have taken a couple of objects obj1 and obj2 both have person properties on them and also they are referencing to same person object in line 1. But when obj1.person() is executed then " this" keyword will reference to obj1 so we will get as "Messi" and exact same thing with obj2. Let's consider another example for the same operation just to make sure where ever function is getting declared binding rule holds true.

See output remains the same and does not affect the behavior. obj1.person() will get “Messi”, obj2.person() will get “Ronaldo” and function binding rule will get as “Micheal”.

3. Apply Invocation Binding

What if we want to force a function to use a particular object for “ this " binding without adding property reference on the object?

If you use .call()and .apply() it lets us to invoke a function and also lets us to choose “ this ". Let's take an example.

When we execute person() it takes function rule binding. When we execute line 8, it is explicitly stating what “ this" should be, In this case, it will be obj1. Same in case of apply() with related to " this ".

4. Constructor Binding

“Constructors” are special methods which are attached to classes, when we are trying to invoke a function with new keyword, the constructor of the class is called.

When a function is invoked with new keyword in front of it, the following things will be happening

  • A new object will be created.
  • The new object which is constructed will be of [[prototype]] linked.
  • The new object which is constructed is set as this binding.
  • It returns the newly constructed object.

In the above example, by calling person() with a new keyword in front of it. It has constructed a new object. The second thing is it will link to another object(prototype). The third thing is this keyword will get bind to newly created person object that we can see from line 2 and line 3. this.firstName is undefined because it is checking in that specific scope and lastName is printing valid. And the last one is if a function doesn't return anything then it will return this.

Overview of binding rules

We have gone through all four rules of binding this in function calls. Let's try to put it simple words

  • Is there a dot? we have to look to the left, that acts like this.
  • Are we seeing a .call() or .apply()? What is passed before the comma that acts like
  • If we try to invoke from the context of the object then this will be? Strict mode it will be pick as undefined and in non-strict mode, it will pick the global value.

Binding exceptions

There are some exceptions to the rules. The this keyword behaves a little weird when we are expecting apples and it gives oranges.

Ignoring “this”

If we pass null or undefined as this parameter to either .apply, .call or .bind those values will be ignored and acts like a function binding rule.

But why any would pass null to .apply or .call? Because, when using .apply or .call null can be passed when we have no specific value to pass for this and we know that neither the function is also expecting this.

In the above example, there is no need of Math in line 2, it can be passed as null. It does not affect the output of the program.

But passing null should be avoided because if you are using a third-party library where they use this keyword. If you pass null it will consider the value from global scope (in the browser it will be window object).

.bind() exception

When we call a function using .bind, it sets this context and returns a function. For example,

We have one more confusion of this context and will see how it can be solved using .bind()

When we pass p.age as the callback to setTimeout we don’t invoke it. Because person context will not be available in setTimeout. We can fix this problem by using .bind()

In this case, we are binding our callback to this context of the person. When it later executed, proper this context will be passed.

Arrow functions

Normal functions have four rules what we just covered. But ES6 introduced a new function which doesn’t abide by any rules that is arrow function.

Instead of using rules, arrow functions will bind this from the enclosing scope. Let's take the above example which we solved using .bind

— END —

You can learn more about scope and hoisting here: scope in javascript

References

Originally published at https://www.allaboutjavascriptworld.com on July 2, 2020.

--

--