-3

Lets say I have this Object:

    api = {
        x: 2,
        func: () => {
            this.x
        }
    }

If I call api.function, how come this is scoped to the window and not api?

If I turn func into a regular anonymous function this is scoped to the api and not the window.

Can anyone explain this to me? I thought the arrow notation inherited the parent this, which is api

ylin6
  • 63
  • 3
  • 1
    `this` is not "scoped to `api`" with a regular `function`, it's dynamically passed depending on how the function is called. – Bergi Aug 03 '17 at 03:48
  • so let me see if I understand. For the regular function, during runtime `api.func`, `this` is scoped to the `api` because `api` is calling it. For the arrow notation, since the arrow notation gets the scope from its parent, during run time, this is the `window`. Is that correct? – ylin6 Aug 03 '17 at 04:04
  • Yes, it doesn't matter how you call the arrow function, it always gets the `this` value from where the function was defined (which should be `undefined` in your case, assuming strict mode). – Bergi Aug 03 '17 at 04:10

2 Answers2

2

Arrow functions inherit this from their lexical scope, meaning the same value that this would mean in the scope they're defined in.

That's whatever this is in the function that contains that code; it has nothing to do with where in that scope you put the arrow function.

SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
  • *"it has nothing to do with where you put the arrow function"* - Um...I know what you meant, but the lexical scope is determined by where you put it, so... – nnnnnn Aug 03 '17 at 03:24
  • @nnnnnn: Good point; clarified. – SLaks Aug 03 '17 at 03:29
  • More generally, "*…`this` in the function that contains that code*" could be "*…`this` in the execution context that contains that code*", since the OP is global code, not function code. – RobG Aug 03 '17 at 03:40
0

Simple explanation: problem is that the function is created before the api object and it is specifically bound to the window in your case because you are in a window scope. If I slightly rewrite your code using ES5 bind you can get the following

const func = function() {
  this.x
}.bind(this); // here this is a window in your case

api = {
    x: 2,
    func: func 
}

This code is equivalent to yours. Here you can clearly see that your function does not belong to the object api.

smnbbrv
  • 19,108
  • 9
  • 62
  • 100
  • 1
    *"This code is fully identical to yours"* - No it's not. Perhaps you meant to say that it is *equivalent*? (Except it isn't, quite: the OP's arrow function returns `undefined`.) – nnnnnn Aug 03 '17 at 03:31
  • Updated the answer. Still I think the main thing is the explanation, not the wording and returned result that does not play here any role – smnbbrv Aug 03 '17 at 03:45