The immediate function is not a closure, strictly speaking, because it does not meet the three criteria for a closure.


The parenthesis operator

The parenthesis operator, also called the grouping operator, can be used in two ways: if the expression is inside parentheses, it evaluates; If it comes after a function, it calls the function

Enclosing the expression in parentheses returns the value of the expression

console.log((1+2)); / / 3Copy the code

Enclosing a function in parentheses returns the function itself. If the parentheses follow the function, the function is called, that is, evaluated

console.log((function testa() {return666; })); //function testa() {return666; } console.log(function testa() {return666; } ()); / / 666Copy the code

Note: The parenthesis operator cannot be empty, otherwise an error will be reported

(a); //SyntaxError: Unexpected token )Copy the code

Since parentheses are used to evaluate, an error is reported if a statement is placed within parentheses because the statement returns no value

(var a = function() {return 666});
// SyntaxError: Unexpected token var
Copy the code


Function declaration

Use the function keyword to create a function with the function name, called a function declaration.

function testa() {}Copy the code


Anonymous functions

What about functions created using the function keyword without a function name? That’s an anonymous function.

function() {}Copy the code


4. Function expression

What about assigning an anonymous function to a variable? So that’s the expression for the function.

var testa = function() {}Copy the code

Function expressions prevent the JS engine from parsing functions created using function as function declarations. More on that below.


IIFE (IIFE)

What about executing the function immediately?

Call the function immediately after you define it with function. The Function is called an instant-invoked Function and the full name is IIFE(Imdiately Invoked Function Expression)

1. As mentioned in JavaScript (3) of this series, when code is executed, the function declared is parsed first (the function declaration is promoted), and the function expression is parsed only when it is executed line by line.

2. Function declarations cannot be executed immediately because of their enhancement. Because when a function is declared, js will only parse to the end of the curly braces (}), if followed by (), just a parenthesis operator.

function testa(){
    console.log("testa")
}("666") / /"666"// If followed by an empty parenthesis, an error is reported, as mentioned above.Copy the code

So, I don’t know, did you notice that when you declare a function, you don’t have to use a semicolon after it? A semicolon must be followed by a function expression, otherwise an error will be reported. You can write your own little chestnut to verify.

Anonymous functions cannot be written in isolation, so they cannot be executed immediately.

function (){}
//Uncaught SyntaxError: Unexpected token (
Copy the code

The js engine will treat it as a function declaration to parse, and the function declaration must have a function name, so it will report an error. So, you usually see anonymous functions, passed as arguments, or converted to function expressions.

4. Therefore, only function expressions can be executed immediately

var testa = function (){
    console.log("testa")} () / /"testa"
Copy the code

Mentioned above, the function expression, is blocked the js engine the | | using the function to create the function as a function declaration to parsing.

Note: The javascript engine dictates that if the function keyword appears at the beginning of a line, it should be interpreted as a function declaration statement.

So, the solution is to keep function out of the beginning of the line and have the engine interpret it as an expression.

// Use the parenthesis operator (function(){console.log("666"() ()})function(){console.log("666"}();}();function(){console.log("666"(a) +)}function(){console.log("666"-)} ()function(){console.log("666"(a) ~)}function(){console.log("666")} ()Copy the code

A function declaration can be converted to a function expression, which prevents it from being parsed as a function declaration.

Use of immediate execution functions in closures

1. Execute functions immediately to save state with closures.

Consider the closure example from the previous section:

function makeClosures(i){    
    var i = i;  
    return function(){ console.log(i); }}for (var i=1; i<=5; i++) {
    setTimeout(makeClosures(i),i*1000); } //1 /2 /3 /4 //5Copy the code

Now, let’s simplify it with immediate execution functions:

for (var i=1; i<=5; i++) {
    setTimeout((function(i){
        return function(){
            console.log(i);
        }
    })(i),i*1000);
}
Copy the code

After the first anonymous function completes, the second anonymous function is returned. The second anonymous function is passed in as the first argument to setTimeout. Because setTimeout function carried out five times, so immediately perform every time in the function returns an anonymous function has not been executed, (this is returned to the five anonymous functions), each anonymous functions inside holds each incoming, therefore, every I is not the same, so, get the desired results

2, immediate implementation of functions with modular closure applications

(function(){
    var meg = "hello zdx";
    
    function say(arg){
        arg = arg || meg;
        console.log(arg)
    }
    
    window.say = say;
})(window)

window.say();

//"hello zdx"
Copy the code

First, execute the function immediately, it is an anonymous function, you do not get its function reference, thus avoiding global variable contamination. Second, due to the rules of function scope, variables, functions, etc., cannot be accessed outside anonymous functions. As a result, block-level scopes are often modeled with immediate execution functions.