0

Given this class

class Car {
  foo() {
    console.log(this)
  }

  bar = () => {
    console.log(this)
  }

  baz = function() {
    console.log(this)
  }
}


let car = new Car();

let a = car.foo;
let b = car.bar;
let c = car.baz;



a() // undefined

b() // car object

c() // undefined

How come the property assigned arrow function binds the value of this at it's declaration ?

I thought arrow functions use the this value of the execution context, not declaration.

Lev
  • 13,856
  • 14
  • 52
  • 84
  • 1
    Because that is what arrow functions are designed to do. You thought wrong. – Quentin Dec 20 '17 at 15:47
  • 1
    The code you posted is not ES6. You seem to be using the *class fields* proposal. – Felix Kling Dec 20 '17 at 15:48
  • A lambda is equivalent to declaring a bound function with the same scope as the enclosing code. – Brian Dec 20 '17 at 15:49
  • 1
    (picking up Felix's point) ...which when translated to ES2015 ("ES6") is basically `this.bar = () => { /*...*/ };` in the constructor. Since arrow functions close over `this` instead of having their own, `this` within that function refers to the instance. – T.J. Crowder Dec 20 '17 at 15:50

2 Answers2

2

This is not ES6 code. You are using the class fields proposal. Class fields are basically just syntactic sugar for writing code that normally goes into the constructor.

The ES6 equivalent would be

class Car {
  foo() {
    console.log(this)
  }

  constructor() {
    this.bar = () => {
      console.log(this)
    };

    this.baz = function() {
      console.log(this)
    };
  }
}

I thought arrow functions use the this value of the execution context, not declaration.

I'm not quite sure what you mean by this but the this value inside an arrow function resolves lexically, just like any other variable. And the this value of the enclosing execution context is already set when the arrow function is defined.

Given how class fields work we can now see why the arrow function has the reference to the instance: Inside the constructor this refers to the instance and arrow functions resolve this lexically.

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

Until arrow functions, every new function defined its own this value (a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an "object method", etc.). This proved to be less than ideal with an object-oriented style of programming.

Source

codejockie
  • 9,020
  • 4
  • 40
  • 46