The lexical value of this
for your obj
declaration is module.exports
. That's the value of this
when your obj
variable is declared.
So, that explains why obj.scope
is module.exports
because that is the value of this
at the time your object is declared and initialized with your code scope:this,
As you seem to already know, the arrow function declaration when called with an object as in obj.func1()
does not carry through obj
as this
. Instead, it uses the lexical version of this
(what it was at declaration time). As obj.scope
shows, that lexical value of this
is module.exports
. So, the result of console.log("1",obj.func1())
is module.exports
as expected (because func1
is defined as an arrow function.
Then, with obj.func2()
, that is declared as a normal function so the value of this
inside of func2
, when called as obj.func2()
will be obj
. This is how method function calls like obj.func2()
work in Javascript (as long as the function is a normal function definition or method definition, not an arrow function).
Lastly, when you do this:
const newFunc2 = obj.func2;
You are getting a reference to JUST the func2
method, all by itself. You've isolated just the method and it has no association at all with the object any more. So, when you call it like this:
console.log("newFunc2",newFunc2());
The object referenced for obj
is completely gone and the this
value will be set the same as any plain function call will be. The value of this
will be set to undefined
if you're running strict mode or to the global
value if not running strict mode.
For a bit of a review of how all this works or a reference for the future, see:
The 6 ways the value of this is determined inside a function at execution time.