ES6 arrow function and lexical scope inside a function [duplicate]

When you define a and d, the value of this is the top-level window object, since you're not in the context of some other object, and this gets saved in the arrow functions. window.name is an empty string, so that's what you see when you call a.func() and d.func().

Arrow functions should generally not be used as method functions because they don't get access to the object they're called through. Use them when you want to preserve the binding of this from where you created them (just like other closure variables).


For the A case, you literally are preserving this all the way back to window (if ran in a browser), so it would be window.name that you are returning.

As for D however, it was returning blank still because it was on the function level of "this" that was returning. In your case, since you aren't creating a new instance of D but using d as a functional object itself, this points also to window. (I'll post more about the later, but for now, here is an example).

let e = function(){
  this.name = "Elizabeth2"  //this is on the functional level
  return(
    {
      name:"Elizabeth1",
      func: () => console.log(this.name)
    }
  )
}
e().func();       // Elizabeth2 
                  // even though it is on the functional level, the way you're calling it here makes this.name == window.name;
let ee = new e(); // however, imagine if you did this kind of a call instead
ee.func();        // Elizabeth2
                  // this is also on the functional level, HOWEVER, it is not binding this.name to window.name
ee.name;          // Elizabeth1
e().name;         // Elizabeth1
e()['name'];      // Elizabeth1
e();              // {name: "Elizabeth1", func: ƒ}

now to show difference if func is bound to anonymous function rather than anonymous arrow function.

e = function(){
  this.name = "Elizabeth2"
  return(
    {
      name:"Elizabeth1",
      func: function(){console.log(this.name)}
    }
  )
}
e().func();  // Elizabeth1
e().name;    // Elizabeth1
e()['name']; // Elizabeth1
e();         // {name: "Elizabeth1", func: ƒ}