1
var obj = {
    a: 2,
}
var a = 3;

const func = () => {
    console.log(this.a);
}

function test() {
    setTimeout(func, 100);
}

function test2() {
    setTimeout(() => {
        console.log(this.a);
    }, 100);
}
test.call(obj); //3
test2.call(obj); //2

It seemed that the test and test2 are the same, but the returned result is different, what's the problem with 'this'?

fynmnx
  • 571
  • 6
  • 29
gogole
  • 11
  • 2
  • Does this answer your question? [How does the "this" keyword work, and when should it be used?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work-and-when-should-it-be-used) – pilchard Jul 24 '22 at 17:26
  • Arrow functions establish `this` based on the scope in which they are defined, so in the case of `func` it is the global scope, where as the second is defined within `test2` and so takes on `this` of the enclosing function. If you defined `func()` inside `test()` you would see them ouput the same values. The [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#call_apply_and_bind) are always a good place to start. – pilchard Jul 24 '22 at 17:38
  • This is in contrast with standard function declarations, which establish `this` based on where they are called (outside of explicit bindings such as `call` and `bind`). `setTimeout` will call the passed callback in the global scope, so if you were to pass a standard function to the timeout in `test2()` you would see it log `3`. – pilchard Jul 24 '22 at 18:12
  • Thank you very much. I thought that this problem may related to the execution context, and I googled for a while and the asnwer I found is similar to what you said. And for the setTimeout, I found that the scope of arrow function is taken from where the function is declared. – gogole Jul 24 '22 at 18:33
  • Yes, that's really what's at the heart of the output you're seeing, though curiously it doens't matter if `func()` is an arrow function or standard function in the case of `test()` as both will return `3` (the global property) but for different reasons. The arrow function carries the global this with it, while the standard function will access the global this because that is the context in which `setTimeout` will call it. The main difference is that you could `bind(this)` to `func()` if you declare it as a standard function. [jsfiddle](https://jsfiddle.net/o1da2m3j/) – pilchard Jul 24 '22 at 19:54

1 Answers1

5

with test arrow function, this will refer to the window object, and as var a = 3, the a will be assigned as a property to the window, it will be like

window.a

But in test2 this will refer to the obj object.

Mina
  • 14,386
  • 3
  • 13
  • 26