I'm trying to figure out why an arrow function in an object literal is called with window
as this
. Can someone give me some insight?
var arrowObject = { name: 'arrowObject', printName: () => { console.log(this); } }; // Prints: Window {external: Object, chrome: Object ...} arrowObject.printName();
And an object that works as expected:
var functionObject = { name: 'functionObject', printName: function() { console.log(this); } }; // Prints: Object {name: "functionObject"} functionObject.printName();
According to Babel REPL, they're transpiled to
var arrowObject = { name: 'arrowObject', printName: function printName() { console.log(undefined); } };
And
var functionObject = { name: 'functionObject', printName: function printName() { console.log(this); } };
Why isn't arrowObject.printName();
called with arrowObject
as this
?
Console logs are from Fiddle (where use strict;
isn't used).
An arrow function doesn't have its own this value and the arguments object. Therefore, you should not use it as an event handler, a method of an object literal, a prototype method, or when you have a function that uses the arguments object.
It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.
While in ES5 'this' referred to the parent of the function, in ES6, arrow functions use lexical scoping — 'this' refers to it's current surrounding scope and no further. Thus the inner function knew to bind to the inner function only, and not to the object's method or the object itself.
Note that the Babel translation is assuming strict mode, but your result with window
indicates you're running your code in loose mode. If you tell Babel to assume loose mode, its transpilation is different:
var _this = this; // ** var arrowObject = { name: 'arrowObject', printName: function printName() { console.log(_this); // ** } };
Note the _this
global and console.log(_this);
, instead of the console.log(undefined);
from your strict-mode transpilation.
I'm trying to figure out why an arrow function in an object literal is called with
window
asthis
.
Because arrow functions inherit this
from the context in which they're created. Apparently, where you're doing this:
var arrowObject = { name: 'arrowObject', printName: () => { console.log(this); } };
...this
is window
. (Which suggests you're not using strict mode; I'd recommend using it where there's no clear reason not to.) If it were something else, such as the undefined
of strict mode global code, this
within the arrow function would be that other value instead.
It may be a bit clearer what the context is where the arrow function is created if we break your initializer into its logical equivalent:
var arrowObject = {}; arrowObject.name = 'arrowObject'; arrowObject.printName = () => { console.log(this); };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With