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.
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.
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