0

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?

3 Answers3

2

The lexical value of this for your obj declaration is module.exports. That's the value of this when your obj variable is declared.

  1. 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,

  2. 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.

  3. 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.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • Thank you for answering. I think I misunderstood the concept of "declaration" before. The `fn` is declared at the time when `func2` is being executed, either `obj.func2()` or `newFunc2()`. But not the time when the `obj` is declared. When `obj.func2()` is executed, the `fn` is declared, and the "this" refers to `obj` at that time for func2, so does `fn`. When `newFunc2()` is executed, the `fn` get declared. Since the method is isolated, the `this` points to `global`, so the `this` in `fn` here also refers to `global`. Is that correct? – combo combo Mar 23 '21 at 05:39
  • @combocombo - For `func2`, the `this` value inside that function is as described in my answer, it's determined by how the method is called. Then, internal to it's execution, it creates `fn` which is an arrow function. At the point where `fn` is declared (each time `func2` executes), the `this` value is determined by how `func2` was called. Whatever that `this` value is will be the `this` value inside of that local `fn` because that's what `this` was when `fn` was declared. – jfriend00 Mar 23 '21 at 05:51
  • @combocombo - When `newFunc2()` is executed, my answer describes what determines the `this` value inside of the `func2` and that then determines what the `this` will be be inside of that local `fn` because it's an arrow function. Since you're creating a new `fn` each time you execute `func2`, it inherits a new lexical `this` each time based on how `func2` was called. – jfriend00 Mar 23 '21 at 05:54
  • ***When newFunc2() is executed, the fn get declared. Since the method is isolated, the this points to global, so the this in fn here also refers to global. Is that correct?*** Yes, that is correct. – jfriend00 Mar 23 '21 at 05:55
0

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()

.

Rifat Bin Reza
  • 2,142
  • 2
  • 8
  • 24
0

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]

  • It's not really correct to say `this` refers to the object it belongs to (your first sentence). The value of `this` can be many different things depending upon how the function is defined and how it is called. There are some circumstances where `this` is an object associated with that method, but that's only sometimes. See [The 6 ways the value of this is determined inside a function at execution time](https://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676) for a more complete description. – jfriend00 Mar 23 '21 at 04:45