Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrow Function in Object Literal [duplicate]

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

like image 614
Dennis S Avatar asked Apr 19 '16 11:04

Dennis S


People also ask

Can we use arrow function in object?

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.

What does () => mean in JavaScript?

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.

Are arrow functions lexical scope?

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.


1 Answers

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

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); }; 
like image 86
T.J. Crowder Avatar answered Sep 25 '22 19:09

T.J. Crowder