lexical this

In a web page, say we create an object that adds event listeners to certain elements on the DOM. Specifically we want to add a click event to a li element.

So we create an object with a function called addGreenClickEvent. This function uses document to select our li element via class name green and proceeds to add the click handler.
In this handler, we attempt to access some data in the other function addGreenClickEvent because that is where we can access color and position by using this.

Note that when a function is within an object, the ‘this’ in that function will reference that object.
If its a standalone function, the ‘this’ within the function will reference the global object.

So now when you run the web page, in your console, you get:

box5 - clickMe executed
green
1

Now when you click on the li element, you’ll get this:


you clicked on green!
This box has color undefined, with position undefined

As you can see in the handler function, the properties color and position is undefined. If you try to log the ‘this’, you’ll see the HTML element you clicked on:

Obviously this isn’t what we want. What we’re trying to do is to get the ‘this’ reference in addGreenClickEvent.

self hack

The ‘self’ hack basically declares a self property and point it to addGreenClickEvent ‘this’ reference.
By using scope, we call self in the event handler function and it works.

output:

This box has color green, with position 1

arrow function

If you use the arrow function, it uses the parent context, which is the ‘this’ inside the method addGreenClickEvent.
Since addGreenClickEvent is a method of object eventAdder, its ‘this’ correctly points to eventAdder.
Hence by using arrow function here, we point the ‘this’ inside the anonymous function to the parent context, which is the ‘this’ inside method addGreenClickEvent, that points to eventAdder obj.

Double Arrow

But what we made the outer function into an arrow function?

You’ll see that our properties are undefined again.

The reason why this is, is because arrow functions points to the parent context. We’re not taking about the calling object anymore, which is what function does. We’re using the arrow function, which looks for the parent ‘this’. The parent context, in this case (‘this’ of eventAdder) is the windows object.

All you have to do is log the ‘this’ reference in addGreenClickEvent function and you’ll see that the Window object gets printed. Here’s why.
When we use the arrow function at addGreenClickEvent, it applies the self hack in the background like so:

So as you can see by using the arrow function for addGreenClickEvent, the this references in that function becomes the global object.
Naturally, the handler function with the arrow function will also apply the self hack, which results in getting the global object for the ‘this’ reference as well.

Hence, in this situation, the right thing to do is to make sure the topmost function’s ‘this’ reference is correct. Then you can keep using arrow functions and it will chain correctly.
But when in doubt, start from the top and use self hack methodology to see what is assigned to each function.

Double function

We first create a function constructor.

We then attach a function called myFriends to its prototype object.
We iterate over an array and then call map on that array. We supply a function for it.

Then we run it.

The problem you will see is that even though our prototype function myFriends has its ‘this’ reference pointing to instance p.
Then when we run myFriends function, we get:


(3) [" is friends with Bob", " is friends with Jane", " is friends with Mark"]

We see that this.name does not display. Let’s simply log the this reference to check.
We see that the ‘this’ reference supplied to map is of the window object.

This is a behavior of es5, where if a function is not attached to an object, it automatically gets set to the global object.

As mentioned earlier, you can simply change the inner function to an arrow function and it will work.

But in our case, we can also use bind:

Unlike call or apply, bind does not execute the function. It simply binds an object to the function for future calls.
When in the future the inner function gets executed by map, its object bound to it will be the ‘this’ in myFriends function.