‘this’ keyword in javascript

Meet Zaveri
codeburst
Published in
5 min readSep 30, 2017

--

As of most used keyword of javascript, “this” will make sense.

Explaining in simple way that “this” keyword written in any scope doesn’t mean that it refers to that function/block scope only.

Scenario A :

Here when foo() is called then it logs out output of 2 because this will search for its object context if it has variable “a” but here we do not have object context (we will learn more about object context in a latter part)as we do not call it via .call( ) or .apply() method. So it will search global object context which include declarations/definitions made in global scope and yes we have variable a as value of 2.

Note this declaration of variable “a” is in global scope so it can also be called global object which refers to global object context.

Scenario B:

Scenario B

Consider this as opposite to previous scenario. Same way here this will absolutely look for object context or global object context situation for “a” as an identifier(i.e. is variable or constant ).

But here there are two call-sites (call sites means that how the function is called). First foo() is invoked , so in its scope there are two things happening: (i) variable named “a” is declared which is in function scope and cannot be accessible by global scope. (ii) it returns this.bar() which means that this will do its duty and will find bar() as if that function is present in object context or global object context. And yes its in global scope so it will be invoked in foo() now it will execute bar() .

So it has only 1 line of code to execute that will be console.log(this.a) as this again searches first for object context (object scope i.e. object that has been binded with that fucntion) or global object context (global scope). So it cannot find variable “a” in neither object context nor in global scope.

Note: remember when we used any undeclared variable in any function or else anywhere , then javascript tells global object to declare it as in global scope . But here when this.a is called , then it does not create global object named “a” because this has particular binding rules.

Talking about the “bindings”

Functions are objects in JavaScript, as you should know by now, if you have read any of the prerequisite articles. And as objects, functions have methods, including the powerful Apply, Call, and Bind methods.

On the one hand, Apply and Call are nearly identical and are frequently used in JavaScript for borrowing methods and for setting the this value explicitly. We also use Apply for variable-arity functions; you will learn more about this in a bit.

Default Binding

Same as Scenario A

Here this hooks up the variable a as of global object namely called “properties” which is probably in global scope. Here in function call, this points out at global object.

Exception: If strict mode is in effect (i.e. “use strict” ) , then the global object is not eligible for the default binding. So value returned would be undefined because this points to undefined in strict mode

Implicit Binding

Implicit Binding using object context

Here before going to global object properties, this goes into its object context to which it has binding because of foo property which is storing foo() function as method.

So because of that foo property of obj it has its value as foo() function which is generally storing address and when console.log(this.a) occurred it can refer to its own property name a which is its own object context.

Thus it does not search a as global object because object context has higher precedence than global object .

Explicit Binding

Explicit Binding via call( )

Previously in implicit binding we were calling functions via object but here we explicitly bind specific object in function call.

It’s call binding syntax can also be seen as foo.call(object context to be bind) which if there is no parameter i.e. empty parenthesis would directly point to global object context.

Hard Binding

Consider scenario here before setTimeout() function: when we create a function bar() , it manually calls foo.call(obj) thereby forcibly invoking foo with obj binding for this .

Next when bar() is invoked, then also that manually process is done no matter whatsoever happens.

This is both explicit and strong binding , so we call it “hard binding”.

The most typical way to wrap a function with a hard binding creates a pass-thru of any arguments passed and any return value received:

Note : apply( ) is used for if we want to pass object context and additional arguments i.e. syntax like apply(object context, arguments) .

Pitfalls : Implicitly Lost due to function reference/alias

Even though bar appears to be a reference to obj.foo, in fact, it's really just another reference to foo itself. Moreover, the call-site is what matters, and the call-site is bar(), which is a plain, un-decorated call and thus the default binding applies.

Mostly unexpected way this occurs is when we consider passing a callback function:

Conclusion

This all explanation were the notes I wrote down during “frontend masters” course by kyle simpson.

Apologies, if any error is there in this article regarding wrong javascript prediction, language error, any code of conduct violation or maybe unwanted explanation.

Cheers!

--

--

Solutions Engineer at Hasura, passionate about web and open source. Created craftbase.org