First, a couple points:
- You should not write code like this that depends upon some implicit value of
this
that is inherited from the environment. If you mean to access the global object, then write code that explicitly references the global object.
- If you run this code in
strict mode
which was designed to prevent common programming mistakes and problems, this code will not run. It will throw an exception. This is a further hint that you shouldn't be writing code like this.
This code depends upon two defaults for the value of this
.
First, it depends upon the top level value of this
. In a browser that will be the window
object. In a nodejs module, that will be the module.exports
object for the current module.
Second, it depends upon what the value of this
will be in your function call xyz()
. In sloppy mode in the browser, that will be window
. In sloppy mode in nodejs, that will be the global object. So, this.man = "XYZ"
is setting a property on the global object. In strict mode, the value of this
inside the xyz()
function will be undefined
.
Third, your assignment of this.man = "ABC"
depends upon what the lexical value of this at the point of definition of your top level arrow function. In the browser, that will also be window
. In nodejs, that will be module.exports
.
So, in a browser, your xyz()
function sets window.man
to "XYZ"
, then it sets window.man
to "ABC"
.
In nodejs, your xyz()
function sets global.man
to "XYZ"
and then your arrow function sets module.exports.man
to "ABC"
.
Lastly, run this in strict mode by inserting:
"use strict";
As the first line of code in the file and you will get an error:
TypeError: Cannot set properties of undefined (setting 'man')
because this
inside of the xyz()
function will be undefined
(as it should be) and trying to set a property on undefined
is a TypeError. You set properties on objects.
It is a great idea to run all your code in strict mode. More and more features in the language are automatically run in strict mode such as class methods because it's just better to run your code in strict mode. It doesn't prevent you from doing anything that there isn't a better way to do. It just prevents you from doing things (often accidentally) that you shouldn't be doing.
For a good illustration in nodejs, run this:
let abc = (() => {
function xyz() {
this.man = "XYZ"; // sets global.man
}
xyz();
this.man = "ABC"; // sets module.exports.man
})()
console.log(this == module.exports);
console.log(module.exports.man);
console.log(global.man)
You will get this output:
true
ABC
XYZ
One other point here is that when you call a function such as xyz()
, the value of this inside the execution of xyz()
is determined by how the function is called. You can see an explanation of the various ways a function can be called here and how that affects the value of this
inside the function.
Calling it as just a plain function xyz()
in sloppy mode will set the value of this
inside that function to the global object. Calling it as a plain function in strict mode will set the value of this
inside that function to undefined
.