Max Koretskyi
Max Koretskyi

Reputation: 105517

what's the purpose of `new Function("return this")()` in immediately invoked function

I'm reviewing the setImmediate polyfill and it's wrapped inside immediate-invoking function with the following:

(function (global, undefined) {
    "use strict";
...
}(new Function("return this")()));

I'm confused about the purpose the last statement and the parameters being passed to the function. Does it have something to do that this code might be run inside a browser as well as on Node.js? Can you please clarify?

Upvotes: 6

Views: 2935

Answers (3)

jack.lin
jack.lin

Reputation: 15

get the global object whatever the js runtime is;(eg node, browser and so on);

Upvotes: -1

Oriol
Oriol

Reputation: 288480

In non-strict mode, when a function is called without setting the this value, it will become the global object:

10.4.3 Entering Function Code

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.

Therefore, the this keyword may be way to obtain a reference to the global object:

this; // the global object

The first problem is that this could have been customized (e.g. with apply or call):

(function() {
    this; // `123`, not the global object!
}).call(123);

This can be easily fixed using a self-executing function:

// `this` may not be the global object here
(function() {
    this; // the global object
})();

But there is a more serious problem: this doesn't become the global object in strict mode:

'use strict';
(function() {
    this; // `undefined`, not the global object!
})();

To fix that, you can use a Function Constructor. Even inside strict mode, the new function will be non-strict by default.

'use strict';
(function() {
    new Function("return this")(); // the global object
})();

Upvotes: 10

James Thorpe
James Thorpe

Reputation: 32212

The code is written so it has access to the global scope, without having to know what the object containing that scope is. For instance in a browser the global scope is window, but in other containers that is not the case.

By using the Function constructor, you get direct access to the global scope:

Note: Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called. This is different from using eval with code for a function expression.

So by doing:

(new Function("return this")())

You create and invoke a new function on the global scope, that returns whatever that global scope is. This is then immediately passed to the main function as the global object.

Upvotes: 14

Related Questions