Can let in JS completely replace Iife

Time:2019-11-2

Preface

Recently, I wrote an article about syntax of Java’s Iife pattern to explain why we write immediate execution function expressions in the current way. A few readers criticized the article for being out of date, arguing that block level scope variables introduced in ECMA 2015 made Iife obsolete.

On the contrary, executing function expressions immediately is not out of date at all! For this reason, I decided to write this follow-up article to introduce some common uses of immediate execution function expressions. Note that the following list is incomplete, so if your favorite usage doesn’t appear in the article, I hope you don’t have any bad feelings.

Function scope vs block level scope

The local variable declared by the VaR keyword only acts on the current closure domain. If such a closure function does not exist, a global variable will be created that pollutes the global scope. To prevent this, we can use Iife to create a function with this local variable.


(function(){
varfoo= "bar";
console.log(foo);
})();
foo;// ReferenceError: foo is not defined

The current debate is that we can use block level scope variables introduced in ECMA 2015 instead of Iife to achieve the same effect. Compared to function level scopes, let and const keywords declare local variables that only affect the current block level domain.


{
let foo= "bar";
console.log(foo);
}
foo;// ReferenceError: foo is not defined

However, block level scope variables are not substitutes for immediate function execution expressions. Indeed, if ECMA 2015 is supported, let and const can be used to restrict the use of local variables only within the block level scope that contains them.

If you execute your Java code in an environment that does not support ECMA 2015 (for example, some old browsers). You cannot use the let and const keywords to create block level scope variables. You will have to resort to the classic function level scope method.

Closures and private data

Another use of Iife is to provide a encapsulated scope for local variables that can be accessed in functions returned by Iife. This means that “a closure is created” allows the function to access the local variable, even when the function is executed outside the lexical scope of Iife.

Suppose we want to create a uniqueID function, each time we call the function, we will return a unique ID (such as “ID UU 1”, “ID UU 2”, etc.). In the Iife below, a private count variable (count) is recorded. Each time the count function uniqueID is called, the count will be increased by one. Another function we return in Iife, which returns a new identifier string when called.


constuniqueId= (function(){
let count= 0;
returnfunction(){
++count;
returnid_${count};
};
})();
console.log(uniqueId());// "id_1"
console.log(uniqueId());// "id_2"
console.log(uniqueId());// "id_3"

Note that the count variable count cannot be accessed outside of IIEF. Other than the function returned from IIEF, the variable cannot be read or written. This creates a real private state that can only be modified in a controlled way. Revving module pattern is very dependent on this mechanism.


constcounter= (function(){
let counterValue= 0;
return{
increment(){
++counterValue;
},
get value(){
returncounterValue;
}
};
})();
counter.increment();
console.log(counter.value);// 1
counter.increment();
counter.increment();
console.log(counter.value);// 3

When Iife is used to return a function that “encloses” some local variables to manage private data, neither let nor const can replace it.

Variable rename

Sometimes, you may encounter a situation where two different libraries you are using expose the same global variable name. For example, consider that you are using jQuery while another library specifies a global variable of $.

In order to solve the naming conflict, you can encapsulate a piece of code in an IIEF and pass a global variable (such as jQuery) into Iife as a parameter. Within the function, you can access the parameter value with an arbitrary parameter name (for example, $):


window.$= functionsomethingElse(){
// ...
};
(function($){
// ...
})(jQuery);

No matter what values are assigned to $, in Iife, these values are “masked” and the $parameter always points to the jQuery method.

Capture global objects

When java code is executed in different environments, you use different global objects. When the code runs in the browser, the global object is windows. But in node.js, the global object is global. Since you don’t want to hard code any of these two names when writing general java code, you can use a “wrapping” method as follows:


(function(global){
// ...
})(this);

Whether it is the browser or the environment of node.js, the global parameter will be specified to the global object of the. If you want to learn more about using this technique to capture the details of global objects, move to this post by Todd motto.

Compression optimization

The method of aliasing variable names can also be used to optimize the code, which enables the code to be compressed more effectively. For example:


(function(window,document,undefined){
// ...
})(window,document);

Shorter identifier names make the file smaller. However, if the returned content of HTTP is compressed by gzip or deflate, the size of the file has been effectively compressed. Therefore, if combined with compression algorithm, the marginal income of compression technology will become smaller. So you weigh and compare the size of the returned content, and shorter names may still work.

The above is the whole content of this article. I hope it will help you in your study, and I hope you can support developepaer more.