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!
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.js
is 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?
-
Babel puts everything in strict mode.
undefined
looks correct. – elclanrs Commented Jun 8, 2015 at 6:39 -
1
@elclanrs It is correct from ES5 perspective since code is transpiled to ES5, but in case of arrow function in ES6 it should be
window
. – dfsq Commented Jun 8, 2015 at 6:46 -
2
@dfsq why should it be window? It would be inheriting
this
from the encapsulating object, which isn't defined; not the global. Or am I wrong in thinking that? – vol7ron Commented Jun 8, 2015 at 6:49 - 1 developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – vol7ron Commented Jun 8, 2015 at 6:52
2 Answers
Reset to default 6tl;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 notwindow
in the browser nor is itexports
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.
You are correct in principle, as described on MDN. However, Babel always places a 'use strict'
at the root scope. In effect you pile the following:
'use strict';
var f = () => { 'use strict'; return this};
In that case strict rules do apply. See the piled example here. Babel even optimizes away the top-level this
as it is guaranteed to be undefined
.