‘this’ keyword in javascript
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:
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
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
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
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!