es6-logo

The little catch(es) with Arrow Functions inside Accessors and Methods

Arrow functions are shorthand notation for function expressions. Although the catch is with the binding of this keyword in the context of accessors

Follow the code snippet below:

'use strict';
var obj = {
  a: 10
};

//Snippet A:
Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this);
    return this.a+10; // represents global object 'Window'
  }
});

//Snippet B:
Object.defineProperty(obj, "b", {
  get: function() {
    console.log(this.a, typeof this.a, this);
    return this.a+10; // represents current object 'obj'
  }
});

Though the snippets A & B may appear to be working alike, the only catch is with this binding, in the snippet A, where the arrow functions doesn’t bind the this keyword as expected.

I’m a little puzzled, not sure if it’s a bug or a feature, because MDN mentions:

An arrow function does not create it’s own this context, rather it captures the this value of the enclosing context

 

The binding of lexical this takes place differently in case of Arrow functions.

Examples below:

'use strict';
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); // prints undefined, Window
obj.c(); // prints 10, Object {...}

Common Assumption: this.i should behave like any other function inside. NO.

 

Another example involving call (yanked from MDN):

var obj = { base: 1 };
var f = v => console.log(v + this.base, this);
var g = function ( v ) { console.log(v + this.base, this); };
f.call(obj, 2); // logs NaN, Windows
g.call(obj, 2); // logs 3, Object { base... }  

 

The anomaly in the aforementioned snippet ‘A’ is an ‘expected behavior in ES6’ albeit not anticipated in ES5.

Therefore, it can be safely concluded that arrow functions  can well be used for functions, but they are not ideal candidates for Methods. And, as MDN quotes:

Arrow function expression are best suited for non-method function

 

Bonus: Here is a little mindfuck to play around. Try to guess the output.
(() => ({ foo: () => ({ foo: () => ({ foo: () => ({ foo: () => ({ }) }) }) }) }))();

What? It was easy? Nice. Try the next
(() => () => () => () => () => ({}) )()()()()();

Pacman much?
(() => () => () => () => () => {})()()()()();

Update: Updated the same code as examples in MDN

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s