how come a property assigned arrow function binds

2019-08-16 00:32发布

问题:

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.

回答1:

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.



回答2:

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