Function scope description

By adding a wrapper function to any code fragment, you can “hide” internal variables and function definitions, and the outer scope cannot access anything inside the wrapper function.

Execute functions now (IIFE)

(function foo() {})(); And (the function foo () {} ()); Is the most common IIFE, in fact, there are ways of IIFE, such as can be used! ~ and so on.

Perform function parameter passing immediately

You can pass parameters to IIFE as follows

(function IIFE( win ) {

})( window );
Copy the code

This makes reference to a global object much cleaner in code style than referring to a variable without the word “global”, and also reduces the number of scoped lookups (RHS).

Another application of this pattern is to resolve the exception caused by an error overwriting the default value of the undefined identifier by naming a parameter undefined but passing no value at the corresponding position, thus ensuring that the value of the undefined identifier is really undefined in the code block.

undefined = true; Function IIFE(undefined) {var a; if (a === undefined) { console.log( "Undefined is safe here!" ); }}) ();Copy the code

Block scope description

Prior to ES6, javascript strictly did not have block-level scope, or some of its syntax could generate block-level scope. Js could only generate block-level scope through with and try/catch. Scopes created from objects with with are valid only in the with declaration, not in the outer scope. The catch clause in the ES3 specification that states try/catch creates a block scope in which declared variables are only valid inside the catch. After ES6 comes out, let implicitly has block scope for its declared variables.

Block scoped garbage collection

function process(data) {
// do somethings
}
var someReallyBigData = { a:1 };
process( someReallyBigData );
var btn = document.getElementById( "my_button" );
      btn.addEventListener( "click", function click(evt) {
          console.log("button clicked");
}, /*capturingPhase=*/false );
Copy the code

The click callback of the click function does not require the someReallyBigData variable. In theory this means that when process(..) After execution, data structures that take up a lot of space in memory can be garbage collected. However, because the click function forms a closure that covers the entire scope, the JavaScript engine will most likely still hold this structure (depending on the implementation).

Block scope eliminates this concern and makes it clear to the engine that there is no need to save someReallyBigData anymore, as follows:

Function process(data) {// Do something interesting here} // The content defined in this block can be destroyed! { let someReallyBigData = { .. }; process( someReallyBigData ); } var btn = document.getElementById( "my_button" ); btn.addEventListener( "click", function click(evt){ console.log("button clicked"); }, /*capturingPhase=*/false );Copy the code

Variable ascension

Both function declarations and variable declarations are enhanced. But one notable detail (which can occur in code with multiple “duplicate” declarations) is that functions are promoted first, before variables. Wherever a declaration in a scope appears, it is processed first before the code itself is executed. This process can be visualized as all declarations (variables and functions) are “moved” to the top of their scope. This process is called promotion. The declaration itself is promoted, but assignment operations, including assignment of function expressions, are not.

reference

You don’t know js