Reputation: 95
I have a question about what the "this" points to in an arrow function:
// run this file in nodejs by: node test_this.js
const obj = {
scope:this,
func1:()=>{return this},
func2:function(){
const fn = ()=>this;
return fn();
}
}
console.log("0",obj.scope); // module.exports
console.log("1",obj.func1()); // module.exports
console.log("2",obj.func2()); //obj
const newFunc2 = obj.func2;
console.log("newFunc2",newFunc2()); //global
As I konw, arrow function has no own "this". The scope determines the "this" once the arrow function is declared, and it will never be changed. But why the console.log("2",obj.func2());
outputs the obj
? and why console.log("newFunc2",newFunc2());
print a different result global
?
Upvotes: 0
Views: 573
Reputation: 707396
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.
Upvotes: 2
Reputation: 11
The JavaScript this keyword refers to the object it belongs to.
It has different values depending on where it is used:
In a method, this refers to the owner object. Alone, this refers to the global object. In a function, this refers to the global object. In a function, in strict mode, this is undefined. In an event, this refers to the element that received the event. Methods like call(), and apply() can refer this to any object.
In strict mode, when used alone, this also refers to the Global object [object Window]
"use strict"; var x = this; // x equals [object Window]
Upvotes: 0
Reputation: 2761
When you're assigning obj.func2
to newFunc2
, the function is copied to the new variable, having no connection with the obj
anymore. So when you are calling newFunc2()
, it's referring to the window object by this
in that scope. Below example demonstrate that obj.func2
when defined, doesn't have any information of className
. When we copy the function func2
in the class MyObj
, this
now refers to the new class, hence you get the log this.className = 'MyObj'
const obj = {
scope:this,
func1:()=>{return this},
func2:function(){
const fn = ()=>this;
console.log(this.className)
return fn();
}
}
class MyObj {
constructor() {
this.className = 'MyObj'
this.obj()
}
obj() {
this.func2 = obj.func2
}
print() {
this.func2()
}
}
var myObj = new MyObj()
myObj.print()
.
Upvotes: 0