Understanding JavaScript ‘this’ bindings

I’ve been there, I’ve had my share of troubles in the beginning to understand what was wrong with my code, especially for a person coming from a background of family of strictly typed languages. It was tough understanding the bindings and the use of ‘this’ keyword. With time, I was able to understand the nitty-gritties of the language. This post is my attempt to reinforce myself with the things I’ve learned and explain others — the bits of the language in the best way I can.
Implicit Binding
In implicit binding, you can’t really tell what the result of this is going to be before hand til you know which function or operation is being invoked, the rule for this is pretty simple. To find out what your this keyword is referring to, you look to the immediate scope of the left to the dot call operation. This is the most commonly used and its probably how you already know how ‘this’ keyword operates in JavaScript, but it can get pretty confusing, so hang in there.
In this case, we used ‘this’ keyword in two cases- this.name and this.age , I hope it’s pretty easy to understand, the name would be “Matt Murdock” and the age would be “28” since both of these lie in the same immediate scope of myObject and that’s what ‘this’ would be referring to. If we look to the left of the dot call operation, it is myObject.
Let’s take it up a notch. Take some time to understand what’s happening here.
If you look carefully, the two objects DonInventory and JackInventory are being called into InventoryDetails and have their own individual reference. These are two different objects referring to two different set of values. To find out which values this is referring to. Look to the left of the dot operation and find the immediate scope of that variable. In this case,
JackInventory.GetInventoryDetails() logs the name, pens, pencils by accessing the JackInventory object and their values.
A little bit of more practice won’t hurt.
Just similar to the above example, Company is a function that takes two arguments and returns an object. As discussed, the rule says, you need to look at the immediate scope of the object that this invoked function or object is referring to. newCompany.getNetWorth is loggingHex etc. If you noticed the one level deeper values of company2, you can see that newCompany.company.getNetWorth()'s this is referring to different values compared to newCompany.getNetworth() function. Look to the left side of the dot call operator of getNetWorth()
Explicit Binding
//call, apply, bind
I think it’s pretty clear so far that using this in JavaScript can be messy and sometimes confusing as opposed to other strictly typed languages since there is no intrinsic relationship between the function and any of the objects, as we really don’t have classes in JavaScript. Because in JavaScript, if this doesn’t reference something, it could reference a global object, this could be dangerous. For instance,
// someFunc:function(){
// return this.x;
// }var func = Obj.someFunc();
func(); // Could refer to global variable 'x'
I’ve had a lot of cases where this in my code referred to the window object or undefined when in strict mode. Nobody wants code that’s so unpredictable. To take full advantage of “Explicit” binding in JavaScript, you need to use the built-in call and apply methods.
call ()
You would want to use a call function to control the scope of the function that’s called. This allows us to write a lot of reusable code (if written correctly), you could use these functions without restricting them to a specific object. You’re typically binding this function to whatever object you want to use it with. A clearer example would be, instead of rewriting getHealth() function a hundred times for every RPG player in your game. You could write the function once and bind it with the specific object you want it to be called with in run-time and use it without any problems. It’s great to know the scope of the function before hand and less prone to errors(or worse, reference global objects).
apply()
this function (see what I did there?), so this function is another in-built function in JavaScript to explicitly bind a function to an object and apply the array of arguments to it, hence the name.
This is same as the call function binding, but this function would be more useful if you have a long list of arguments to pass to a function. You can just pass in an array when you call the apply function. If you’ve a DOM that needs to update, instead of calling the function and individually applying them to the function and making it look something like this -
func.apply(with, so , many, arguments, that, i , lost , count, what, am , i , doing, send, help);
You could just store all of these in an array and do something like this
func.apply(myArrayOfArguments)
bind()
Bind is another function that is very similar to apply(), but instead of invoking the function on call, it is going to return the function so you can invoke it later when you please.
var myInvokedFunction = func.bind(object, argument1, argument2,argument3...);You could later call this function by calling myInvokedFunction . Easy does it. I use this extensively in my front-end projects. Helps me know before hand if I know what data to process and use later in the programs just by calling the reference function.
new Binding
You’d typically use the new keyword to create new instances of objects in JavaScript that simulates the feel of classes in other languages like Java, C++ etc, even though they aren’t really classes.
This is how you’d bind the new object with a function using the new keyword to create the object. Similar to the one’s you’ve seen in the above examples, I’m using the call function to bind the object to the function.
window binding
It’s all well and good that we’re able to understand how the binding works, although, there are a couple of red-flags when working with JavaScript, especially when not working in strict mode . If you’re not careful enough, you might be using variables that you didn’t even mean to in the first place.
Let’s modify the above example a bit.
With a few modifications of the above example, you can see the catastrophic results the code can have if you don’t bind your functions properly. In this case, the variables used wouldn’t be generally used in a normal program. But if ever, there’s a global variable with the same name of that of yours, the results can be similar to this. So be wary of referencing the global variables, always bind your functions with extra care.
I hope this post has been of some value to you and you’ve picked up something from here that you could use in the future in your development journeys. If there’s something wrong with what I just wrote, I’d love to learn and correct myself, or if you’d like to add anything, please let me know in the comments.
You can follow me over here for random dev posts, I also have a GitHub if you want to stay updated on my latest projects.