Search code examples
javascriptscopeecmascript-6babeljslexical-scope

Compiling ES6 arrow functions to Es5 using Babel.js




While looking into ES6 arrow functions' documentation on Mozilla documentation, I got to know that Arrow functions applies all the rules of strict mode, except one as described in the link

  var f = () => { 'use strict'; return this};
    var g = function () { 'use strict'; return this;}

    console.log(f()); //prints Window
    console.log(g()); // prints undefined

    //we can test this in firefox!

But, Babel.jsis transpiling the arrow function code to ES5 code that returns undefined rather than Window(demo link)

"use strict";

setTimeout(function () {
  return undefined;
}, 100);

So, the above snippet is the output from Babel.js. Couldn't it be the below output?

"use strict";

setTimeout(function () {
  return this;
}.bind(Window), 100);

If I am writing ES6, I would expect Window rather than undefined
Is it a bug?
OR, I misunderstood anything?


Solution

  • tl;dr: Babel assumes every file is a module. Modules are strict by default and their this value is undefined.


    This is covered in the Babel FAQ:

    Babel assumes that all input code is an ES2015 module. ES2015 modules are implicitly strict mode so this means that top-level this is not window in the browser nor is it exports in node.

    If you don't want this behaviour then you have the option of disabling the strict transformer:

    $ babel --blacklist strict script.js
    
    require("babel").transform("code", { blacklist: ["strict"] });
    

    PLEASE NOTE: If you do this you're willingly deviating from the spec and this may cause future interop issues.

    See the strict transformer docs for more info.