1
let o = {
  x: 1,
  foo() {
    setTimeout(()=> 
      console.log(this.x),
    100);
  }
}
o.foo();

This prints out 1 after 100ms.

Is this because it is equivalent to the following, meaning that the lexical this binding of arrow functions works?

let o = new (function Object() {
          this.x = 1;
          this.foo = ()=> console.log(this.x);
        });
o.foo();
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • No, this does *not* print out `1` after 100ms. It does so only when you call `o.foo()` somewhere! – Bergi Apr 29 '15 at 12:21
  • [Never use `new function(){}`](https://stackoverflow.com/questions/10406552/is-it-right-to-think-of-a-javascript-function-expression-that-uses-the-new-key-as-static) btw – Bergi Apr 29 '15 at 14:19
  • @Bergi - you are distinguishing between the question and your comment by the absence of parens? – Ben Aston Apr 29 '15 at 18:23
  • no, the parenthesis and the naming don't matter. It's the `new`+function expression antipattern that should not be used. – Bergi Apr 30 '15 at 00:56

1 Answers1

1

Is this because it is equivalent to the following, meaning that the lexical this binding of arrow functions works?

No, it's much simpler than that. It's equivalent to

var o = {
  x: 1,
  foo: function() {
    setTimeout(()=> 
      console.log(this.x),
    100);
  }
};
o.foo();

and with the arrow function converted:

var o = {
  x: 1,
  foo: function() {
    var self = this;
    setTimeout(function() {
      console.log(self.x)
    }, 100);
  }
};
o.foo();

Since you are calling o.foo(), this inside foo refers to o. Because an arrow function's this is subject to lexical scope, it access foo's this.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143