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?
An Immediately-invoked Function Expression (IIFE for friends) is a way to execute functions immediately, as soon as they are created. IIFEs are very useful because they don't pollute the global object, and they are a simple way to isolate variables declarations.
It is used in very specific cases, like when we receive code from a server, or to dynamically compile a function from a template, in complex web-applications.
An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.
A function in JavaScript is similar to a procedure—a set of statements that performs a task or calculates a value, but for a procedure to qualify as a function, it should take some input and return an output where there is some obvious relationship between the input and the output.
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.
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
- If the function code is strict code, set the ThisBinding to thisArg.
- 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
})();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With