
Understanding which object context the keywordthis
is referencing is one of the more confusing language features in JavaScript. Even if you have a firm understanding of the rules forthis
binding there is still opportunity for it to surprise you, like when usingthis
in the outermost scope of a Node module.
For comparison purposes, let's see what happens when we usethis
in the outermost scope of a script run in the browser before we try using it in a Node module.
<html><head><title>Which This Is This</title></head><body><script>this.context="is this the global context?"functionwhichThisIsThis(){alert(this.context)}whichThisIsThis()</script></body></html>
Opening the above HTML in a browser creates an alert modal with the text "is this the global context?" displayed, confirming that both references tothis
are for the same context object. If we replacethis.context = ...
withwindow.context = ...
in the first line of the script we get the same text in the alert modal as before, confirming thatthis
is thewindow
object whenwhichThisIsThis
is executed.
Based on the above experiment in the browser, what do you think the following code will print to the console if executed by the Node runtime?
this.context="is this the global context?"functionwhichThisIsThis(){console.log(this.context)}whichThisIsThis()
Surprisingly, it will printundefined
. Unlike in the browser script,this
in the outermost scope of a Node module is not a reference to the global object, rather it is a reference to themodule.exports
object.
However whenwhichThisIsThis
is executed in the example above,this
inside the function's scopeis the global object. Because the outermost scope is setting acontext
property on thethis
that's referencingmodule.exports
, we get an undefined response when trying to access acontext
property on thethis
that references the global object, thethis
inside thewhichThisIsThis
function scope.
You can test this out by changingthis.context
in the call toconsole.log
tomodule.exports.context
. Run the code again and you should see the string value assigned tothis.context
in the outermost scope print to the console.
this.context="this is the module.exports context, not the global context!"functionwhichThisIsThis(){console.log(module.exports.context)}whichThisIsThis()
However if your intention is to use the global object you can keepthis.context
as the argument forconsole.log
but you will need to explicitly create and set acontext
property on the global object.
global.context="this is the global context!"functionwhichThisIsThis(){console.log(this.context)}whichThisIsThis()
Keep in mind that thethis
in thewhichThisIsThis
function is only referencing the global object in the above example because no other context has been provided. If this function were to be called in a way that implicitly or explicitly provided a different object to assume the role ofthis
, the outcome would be different.
global.context="default global context"functionwhichThisIsThis(){console.log(this.context)}letimplicitContext={context:"implicitly bound context",whichThisIsThis}implicitContext.whichThisIsThis()letexplicitContext=whichThisIsThis.bind({context:"explicitly bound context"})explicitContext()
Running the above code will print "implicitly bound context" and "explicitly bound context" to the console but not "default global context".
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse