By Dennis S


2016-04-19 11:43:26 8 Comments

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

1 comments

@T.J. Crowder 2016-04-19 11:47:20

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);
};

@Dennis S 2016-04-19 12:04:12

I was indeed using Fiddle (without "use strict;"). Great answer, I understand what's going on now.

@Salivan 2017-05-11 18:33:25

Great answer. Simple and clear. :)

Related Questions

Sponsored Content

21 Answered Questions

[SOLVED] Self-references in object literal declarations

36 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

34 Answered Questions

[SOLVED] var functionName = function() {} vs function functionName() {}

41 Answered Questions

[SOLVED] Check if object is an array?

  • 2011-01-23 18:53:04
  • mpen
  • 1240743 View
  • 2230 Score
  • 41 Answer
  • Tags:   javascript arrays

41 Answered Questions

[SOLVED] Detecting an undefined object property

64 Answered Questions

[SOLVED] What is the most efficient way to deep clone an object in JavaScript?

42 Answered Questions

[SOLVED] How do I check if an array includes an object in JavaScript?

38 Answered Questions

[SOLVED] Is there an "exists" function for jQuery?

  • 2008-08-27 19:49:41
  • Jake McGraw
  • 679122 View
  • 2406 Score
  • 38 Answer
  • Tags:   javascript jquery

22 Answered Questions

[SOLVED] How can I add a key/value pair to a JavaScript object?

3 Answered Questions

[SOLVED] ECMAScript6 arrow function that returns an object

Sponsored Content