combo combo
combo combo

Reputation: 95

What is "this" in an arrow function in JavaScript

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

Answers (3)

jfriend00
jfriend00

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.

  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.

Upvotes: 2

Shavleg Kakulia
Shavleg Kakulia

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

Rifat Bin Reza
Rifat Bin Reza

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

Related Questions