babel: 'this' becomes 'undefined' in es2015 preset

Bug: when using this at the global level of your js code, using the es2015 or env preset, it will be transformed to undefined, which is not correct.

Input Code

(function($) {
  // ...
}(this.jQuery));

Output

"use strict";

(function ($) {
  // ...
})(undefined.jQuery);

Babel Configuration

Calling babel via gulp:

.pipe(babel({
    presets: [ "env" ]
}))

No config file otherwise.

Expected Behavior

this should not be transformed into undefined. There is no reason to.

Current Behavior

this at the global context is transformed into undefined.

Possible Solution

It works fine in the es2017 preset, so perhaps copy over what that preset is doing, into es2015.

Context

I’m trying to transform modern javascript into javascript that oldIE can understand, and the above code is how we write our top-level IIFE to avoid conflicts in the global context. this in the global context means the window object.

Your Environment

software version(s)
Babel 6.26.0
Babel-preset-env 1.6.1
Babel-preset-es2015 6.24.1
Gulp-babel 7.0.1
node 8.10.0
npm 5.7.1
Operating System Windows 10

Noet: the issue can also be reproduced on the Try it out thing.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

The global this is (and must be) always undefined in modules.

I don’t think that’s a good way to think about it. The module-level execution environment, which is a level above the global scopes, specifically sets this to undefined, which means the global this is still the same, but it is shadowed.

https://www.ecma-international.org/ecma-262/8.0/#sec-module-environment-records-getthisbinding

I’m not so sure about that actually. The global this is imposed by the browser, and cannot be overridden by any script, however crafty. That is the reason I’m using this in favour of window - it’s always available. this can only be undefined in a function context where that function is explicitly called like fn.call(undefined, ...) but this doesn’t and cannot happen for the global context.