Arrow Function in Object Literal
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);
};
Methods in ES6 objects: using arrow functions
Arrow functions are not designed to be used in every situation merely as a shorter version of old-fashioned functions. They are not intended to replace function syntax using the function
keyword. The most common use case for arrow functions is as short "lambdas" which do not redefine this
, often used when passing a function as a callback to some function.
Arrow functions cannot be used to write object methods because, as you have found, since arrow functions close over the this
of the lexically enclosing context, the this
within the arrow is the one that was current where you defined the object. Which is to say:
// Whatever `this` is here...
var chopper = {
owner: 'Zed',
getOwner: () => {
return this.owner; // ...is what `this` is here.
}
};
In your case, wanting to write a method on an object, you should simply use traditional function
syntax, or the method syntax introduced in ES6:
var chopper = {
owner: 'Zed',
getOwner: function() {
return this.owner;
}
};
// or
var chopper = {
owner: 'Zed',
getOwner() {
return this.owner;
}
};
(There are small differences between them, but they're only important if you use super
in getOwner
, which you aren't, or if you copy getOwner
to another object.)
There was some debate on the es6 mailing list about a twist on arrow functions which have similar syntax but with their own this
. However, this proposal was poorly received because that is mere syntax sugar, allowing people to save typing a few characters, and provides no new functionality over existing function syntax. See the topic unbound arrow functions.
Javascript arrow function lexical scope: object literal vs new operator
The new
operator doesn't create a new scope.
Functions create a new scope.
The constructor
function is a different function to the global-outside-of-any-function space.
ECMAScript 6 arrow function that returns an object
You must wrap the returning object literal into parentheses. Otherwise curly braces will be considered to denote the function’s body. The following works:
p => ({ foo: 'bar' });
You don't need to wrap any other expression into parentheses:
p => 10;
p => 'foo';
p => true;
p => [1,2,3];
p => null;
p => /^foo$/;
and so on.
Reference: MDN - Returning object literals
ES6 Arrow function: why this points differently when used in constructor and object literal?
function Obj() {
this.show = () => {
console.log(this);
};
}
const o = new Obj();
o.show();
Here "this" works based on the rules of the "new" keyword, pointing to a new object with the structure defined inside Obj() (the new object is the context).
More info at : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
const o2 = {
show: () => {
console.log(this);
}
}
o2.show() // window || undefinded
Here "this" gets its value at runtime and because neither lambda functions nor object literals define a context, the context remaining is the global one and that is why you get that value.
Related Topics
Check If Object Is a Jquery Object
How to Convert String to Number According to Locale (Opposite of .Tolocalestring)
Is <Boolean Expression> && Statement() the Same as If(<Boolean Expression>) Statement()
How to Redirect to an External Url from Angular2 Route Without Using Component
Sanitizing User Input Before Adding It to the Dom in JavaScript
Window.Onunload Is Not Working Properly in Chrome Browser. Can Any One Help Me
Angularjs Multiple Filter with Custom Filter Function
JavaScript Get Textarea Input via .Value or .Innerhtml
What Are the Actual Uses of Es6 Weakmap
Node.Js Tail-Call Optimization: Possible or Not
"Var" or No "Var" in JavaScript's "For-In" Loop
How Is () => {...} Different from () =>
Using Number as "Index" (JSON)
Convert Time Interval Given in Seconds into More Human Readable Form
How to Check If an Object Has a Key in JavaScript
What's the Best Way to Loop Through a Set of Elements in JavaScript