What does "this" refer to in arrow functions in ES6?
Arrow functions capture the this
value of the enclosing context
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
So, to directly answer your question, this
inside your arrow function would have the same value as it did right before the arrow function was assigned.
Hope this code show could give you clearer idea. Basically, 'this' in arrow function is the current context version of 'this'. See the code:
// 'this' in normal function & arrow function
var this1 = {
number: 123,
logFunction: function () { console.log(this); },
logArrow: () => console.log(this)
};
this1.logFunction(); // Object { number: 123}
this1.logArrow(); // Window
In order to provide the big picture I'm going to explain both, dynamic and lexical binding.
Dynamic Name Binding
this
refers to the object the method is called on. This is a regularly to be read sentence on SO. But it is still only a phrase, pretty abstract. Is there a corresponding code pattern to this sentence?
Yes there is:
const o = {
m() { console.log(this) }
}
// the important patterns: applying methods
o.m(); // logs o
o["m"](); // logs o
m
is a method because it relies on this
. o.m()
or o["m"]()
means m
is applied to o
. These patterns are the Javascript translation to our famous phrase.
There is another important code pattern that you should pay attention to:
"use strict";
const o = {
m() { console.log(this) }
}
// m is passed to f as a callback
function f(m) { m() }
// another important pattern: passing methods
f(o.m); // logs undefined
f(o["m"]); // logs undefined
It is very similar to the previous pattern, only the parenthesis are missing. But the consequences are considerable: When you pass m
to the function f
, you pull outm
of its object/context o
. It is uprooted now and this
refers to nothing (strict mode assumed).
Lexical (or Static) Name Binding
Arrow functions don't have their own this
/super
/arguments
binding. They inherit them from their parent lexical scope:
const toString = Object.prototype.toString;
const o = {
foo: () => console.log("window", toString.call(this)),
bar() {
const baz = () => console.log("o", toString.call(this));
baz();
}
}
o.foo() // logs window [object Window]
o.bar() // logs o [object Object]
Apart from the global scope (Window
in browsers) only functions are able to form a scope in Javascript (and {}
blocks in ES2015). When the o.foo
arrow function is called there is no surrounding function from which baz
could inherit its this
. Consequently it captures the this
binding of the global scope which is bound to the Window
object.
When baz
is invoked by o.bar
, the arrow function is surrounded by o.bar
(o.bar
forms its parent lexical scope) and can inherit o.bar
's this
binding. o.bar
was called on o
and thus its this
is bound to o
.