undefinedfix
Sign in

The problem of arrow function this pointing to

Braino edited in Sun, 17 Jul 2022
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

This inside the arrow function points to the object at the time of definition, not the object at the time of execution. According to this principle, the function inside setTimeout, whether it is an arrow function or not, should point to window. When defining, the internal this should not point to the window. When executing, should it point to the calling object {ID: 42}? Ask for advice

17 Replies
hmhsv
commented on Sun, 17 Jul 2022

Two things are clear

  1. This of the arrow function is determined at the time of definition, which is the scope
  2. This of function can be determined only when it is called. Only when you understand these two points can you continue
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
  1. The arrow function inside function foo is the same as function foo
  2. Next, let's see how to determine this of function foo. We can see that the call method is used, where this is the {ID: 42} object

If it is foo ({ID: 42}), then this is undefined or window (depending on strict mode)

MeineHTMLCodes
commented on Sun, 17 Jul 2022

You can understand that the arrow function gets this wherever it is written. Here, it is obvious to read this directly from the execution environment of foo, and foo is bound by you { id : forty-two } So this naturally points to this object.

JSPDeveloper01
commented on Mon, 18 Jul 2022

call () And apply () Method will change the direction of this.

man
commented on Mon, 18 Jul 2022

This is not a window, but {ID: 42}, foo.call The first parameter of the foo function is this

function foo () { var x = this ; setTimeout (() => {

var y=this;
console.log('id:', this.id);

}, 100);}

This means that both X and Y point to the same this. Obviously, X is {ID: 42}, so is y.

alexfang609
commented on Mon, 18 Jul 2022

Here, this in the arrow function is this in the function foo. When called directly this.id Namely window.id When using call, point this of foo to the {ID: 42} object, and this.id 42.

foo(); // id: 21
foo.call({ id: 42 }); // id: 42
knrtt
commented on Mon, 18 Jul 2022

because . call () The method is to bind this value of foo to obj object first , If foo is executed again, if it contains ID, it will not be found in the prototype chain

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
  
  this.fun =()=>{
    console.log(this);
  }
}
var id = 21;
var obj = { id: 42 };

foo.call(obj);

console.log(obj)

clipboard.png

pydda
commented on Mon, 18 Jul 2022

The arrow function does not have its own this , Its this is inherited. By default, it points to the object in which it was defined ( Host object ) Instead of the object at execution time. For example:

function a() { 
   console.log(this);  //window
}  
a(); 

I believe you should understand when you write here

Originally, this of foo was a window. Later, after calling, this point became {ID: 42}. So the implementation is foo.call ({}), not foo itself. (here's the key!)

If you go to foo again at this time () , Printed or 21

mvgio
commented on Mon, 18 Jul 2022

Foo is not executed. The arrow function in setTimeout has not been defined, just like the following fun. When foo is not executed, there is no fun in memory. Strictly speaking, "this in the arrow function points to the object in which it was defined." it is wrong. The arrow function does not have this. It only inherits this from the upper layer of its scope chain, The rule is the same as the variable TTT in the following code ; Finally, let's look at MDN's explanation of arrow functions

var ttt = '888'
function foo() {
  var ttt = '999'
  setTimeout(() => {
    console.log(ttt) // 999
    console.log('id:', this.id);
  }, 100);

  var fun = () => {console.log(this.id)}
  setTimeout(fun, 100)
}
oamnx
commented on Mon, 18 Jul 2022

If you just want to know the arrow function this points to, I don't know if this example can help you

var test = {

aa:function(){
    console.log(this);
    setTimeout(function(){
        console.log(this)
    },1)
},
bb(){
    console.log(this);
    setTimeout(()=>{
        console.log(this)
    })
}};

test.aa()
    >{aa: ƒ, bb: ƒ}
    >Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    
test.bb()
    >{aa: ƒ, bb: ƒ}
    >{aa: ƒ, bb: ƒ}
 
Tomy
commented on Tue, 19 Jul 2022

one . Ordinary function calls this to point to window

function fn() {
    console.log(this);
}
window.fn();

2. The method call this points to the object calling the method

var obj = {
    fun: function () {
        console.log(this);
    }
}
obj.fun();

3. As a constructor, this inside the calling constructor points to the object created by the constructor

var gf = {
    name : "tangwei",
    bar : "c++",
    sayWhat : function() {
        console.log(this.name + "said:love you forever");
    }
}

4. The object that triggers the event as a handler of the event

btn.onclick = function () {
    console.log(this);
}

5. As a timer parameter, this points to window

setInterval(function() {
    console.log(this);
}, 1000);

Summary: this in the function is determined by the function when it is called

nafischonchol
commented on Tue, 19 Jul 2022

This direction of arrow function is determined by the context in which it is defined.

Ove
commented on Tue, 19 Jul 2022

If you direct foo (), you point to the whole situation, but you write it foo.call () will point to the object you passed in. This is because this in the arrow function captures the point of this in its outer layer.

user586042
commented on Tue, 19 Jul 2022
fun.call(thisArg, arg1, arg2, ...)

Where thisarg is the value of this specified by the function runtime.

When you run the foo method here, the specified object is {ID: 42} this.id 42, of course.

Reference MDN: HTTPS :// developer . mozilla . org ...

rolly4444
commented on Tue, 19 Jul 2022

Arrow function causes this to always point to the object where the function definition takes effect, while ordinary function always points to the object when the definition takes effect. Here, the definition of arrow function takes effect when foo function is generated, and its real execution will wait until 100 milliseconds later. When it takes effect after 100 seconds, the object is {ID: 42}. http://es6.ruanyifeng.com/#do...

In addition, call changes the scope of the function to point to {ID: 42}

Az104DAYS
commented on Tue, 19 Jul 2022

This in the function passed by setTimeout points to the global object (window). However, the arrow function does not create its own this, it only inherits this from the upper layer of its scope chain

Therefore, this in the scope of foo function should be used, that is, {ID: 42} object specified by call

lock This question has been locked and the reply function has been disabled.