2

I was practicing below code Code Reference : Link

   let obj = {
    name : "Cj",   
    sayLater : function(){
        setTimeout(function(){
          console.log("sayLater :> "+this.name); 
        },3000)
    },
    sayNow : function(){
      console.log("sayNow :> "+this.name); 
    },
    sayLaterFA : function(){
      setTimeout(() => console.log("sayLaterFA :> "+this.name) ,3000)
    },
    sayNowFA : () => console.log("sayNowFA :> "+this.name),
    sayLaterPureFatArrow : () => { setTimeout(() => console.log("sayLaterPureFatArrow :> "+this.name),4000) },
    sayNowPureFatArrow : () => { console.log("sayNowPureFatArrow :> "+this.name) }
  }



 obj.sayLater();             //Output : sayLater :> undefined
  obj.sayNow();               //Output : sayNow :> Cj
  obj.sayLaterFA();           //Output : sayLaterFA :> Cj 
  obj.sayNowFA();             //Output : sayNowFA :> Cj
  obj.sayLaterPureFatArrow(); //Output : sayLaterPureFatArrow :> undefined 
  obj.sayNowPureFatArrow();   //Output : sayNowPureFatArrow :> undefined

Can anyone explain me why my output is undefined though I am using fat arrow function

C J
  • 429
  • 1
  • 10
  • 34

4 Answers4

3

The this value for those arrow functions is the value of this in the context where the functions were created. That's not the object you're constructing; it's whatever this is where that object initializer code exists.

In other words, inside

let obj = {
  // whatever
};

the value of this does not change from what it is before or after that initialization. The language does not provide a way to refer to an "under construction" object in an initializer block.

Pointy
  • 405,095
  • 59
  • 585
  • 614
1

There is no this referring to the object a arrow function is in in an arrow function,

An arrow function expression has a shorter syntax than a function expression and does not have its own this[...]

This will always refer to the object you are calling from, i.e. window in a browser

Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44
  • *"This will always refer to the object you are calling from"* What exactly is that supposed to mean? In an arrow function, `this` is resolved lexically like any other variable. – Felix Kling Jun 06 '18 at 18:37
  • In Case of obj.sayLater(); function has been called but setTimeout has only been initialed.At the time of setTimeout executes the console.log the value of this will be undefined in that function scope.Am I right @Luca – C J Jun 07 '18 at 01:29
  • Your are right, @CJ – Luca Kiebel Jun 07 '18 at 07:28
1

Fat arrows capture the surrounding this value. For an expression in an object literal at the top level of a file, the surrounding this value is window (non-strict mode) or undefined (strict mode).

So the behavior you see is:

  • sayLater: undefined because the inner function uses no this-capturing mechanism (thus this is "lost" and goes back to window / undefined)
  • sayNow: Cj because of the normal this semantics (this is "what's to the left of the ." in a method invocation)
  • sayLaterFA - same as sayNow except that the inner function captured the outer function's "correct" this
  • sayNowFA - poorly named because it's identical to sayNow
  • sayLaterPureFatArrow / sayLaterPureFatArrow - both captured window as this
Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
0

undefiend is shown as output, since this refers to the scope inside the setTimeout() function where name isn't available, hence, undefined

I usually do it something on the lines of

ayLater : function(){ let instance = this;
    setTimeout(function(){
      console.log("sayLater :> "+instance.name); 
    },3000)
},

Hope this answers :)

Aseem Upadhyay
  • 4,279
  • 3
  • 16
  • 36
  • 2
    This is not accurate; the question is not about the behavior of `setTimeout()` but about how the arrow functions are created. – Pointy Jun 06 '18 at 17:52
  • Also, if `this` was undefined then `this.name` would throw. `this` simply refers to the global scope when the arrow function is not within another function scope. – Patrick Roberts Jun 06 '18 at 17:53
  • Yes, both of you are correct. There was a slight misunderstanding on my side. Also, have updated my answer to rectify – Aseem Upadhyay Jun 06 '18 at 17:55
  • yeah @AseemUpadhyay if we do it your way it will print the the name for sure.. As instance will hold the value of variable. – C J Jun 07 '18 at 01:24