preface

Today is not easy to free, re-review the JavaScript syntax foundation, especially about “expression”, “statement”, “scope” and other aspects, feeling, go back to look at the understanding of “immediately execute function expression”, found that the understanding is deeper, so here to record my understanding process, Also interested in children’s shoes can see 😂.

PS: limited by my ability level, if there is a wrong understanding of the place, please give advice!

A brief

The Immediately Invoked Function Expression, short for IIFE, is a JavaScript Function that is Invoked Immediately when defined.

“Execute function expression immediately” is used to make up for the deficiency of SCOPE in JS. In early JS, there were only “global scope” and “function scope”. There are no more specific local scopes (such as ES6’s “block scope”), so when we need scope isolation, we often use “function scope” in context code to simulate the desired local scope, and such functions are executed only once. So function names and calling statements can be omitted.

(function() {
  console.log("IIFE"); }) ();Copy the code

The whole thing looks like an anonymous function that is called immediately. Here is the recommended format:

; (function() {
  // Independent scope
  console.log("IIFE"); } ());Copy the code

The semicolon in front; Can effectively solve the code merge may produce syntax errors, the same application such as webpack compilation.

Principle of immediate execution

The immediate execution principle of immediate function expression is expression.

The definition of “expression” usually refers to an expression that may result in an operation by linking operands with an operation symbol. In the JS engine we can execute a “function expression” immediately, but not a “function declaration statement” immediately. As follows:

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

If we execute the above code, we will throw a syntax error that marks an exception. Let’s verify the problem step by step and proceed with the following code:

(1); / / 1
function test(){},1); //1, but the function is not executed(a)// Uncaught SyntaxError: Unexpected token ')'
Copy the code

Function test(){}(); function test(){}(); Is a whole, but for the JS engine is unrelated to the two parts, one is the “function declaration statement”, the other is the “parenthesis operator (used to control the priority of the operation)”, even throw syntax error, is also because the parenthesis operator operand can not be empty.

Function test(){}(); The understanding of:

function test() {}; // Function declaration statement.(a);// The parenthesis operator, but the operand is empty, so an error is reported
Copy the code

We must consider that JS syntax allows us to omit semicolons in some scenarios; The use of.

So use a pair of circular brackets(a)The beautiful illusion that you can execute a function declaration statement comes from this hidden semicolon;.

Can we execute a “function declaration statement” immediately? The answer is yes! Starting from the source, since the semicolon is not visible to developers, we totally can also let the semicolon for JS engine is not visible, just let the semicolon disappear, then the function declaration statements and followed behind FuFu parentheses operations can be seen as a whole, which can be the correct recognition and execution.

Before that, let’s strengthen the cognitive level of our basic theory:

  • Function declaration statement: a statement used to create a function that returns a “function value” of a reference type.
  • Function expression: According to the general definition of “expression”, here refers to the “function value” linked to the expression by the operator.
  • A statement is simply an expression and a semicolon;The combination of
function test(){}; // create a 'test' function.
var f = function(){}; // Function expression (function assignment expression).
Copy the code

Since a “function declaration statement” is used to create a function (value) of a reference type, it is reasonable to assume that the function declaration acts as a placeholder that actually represents the function (value) of a reference type. At this point, if we use an “operator” to operate on a function declaration statement, is that the same thing as operating on the function value? This is the feedback from the actual test, so that when we use an operator to operate on a function declaration statement, we will recreate a function expression whose operands are the functions represented by the function declaration statement.

For example, the following assignment expression:

var f = function test() {
  console.log("IIFE");
}
Copy the code

During assignment, the function declaration on the right-hand side assigns the created function to the variable f on the left-hand side, so the function declaration on the right-hand side is essentially a function-valued operand. What if we appended a pair of parentheses to the function declaration?

var f = function test() { console.log("IIFE"); } ();//IIFE
f; //undefined

var f = function test() { reutn 'IIFE'} (); f;//IIFE
Copy the code

We can see that the function created by the function declaration statement is executed and assigned the result of execution to the variable f, where the first is the default value undefined and the second is IIFE. Of course, there are associative operators involved. For example, the assignment operator is left associative. So the function value on the right is executed first (when the function is called immediately).

In the same way, we can use the () round bracket operator to form a “function expression” with a function declaration. Then execute the function value operand of the expression, or the result of executing the expression. (The parenthesis operator returns the operand itself, in this case the function itself to be executed immediately.)

Æ’ IIFE() {console.log('IIFE')}
(function IIFE() {
  console.log("IIFE");
});

//IIFE
(function IIFE() {
  console.log("IIFE"); }) ();//IIFE
(function IIFE() {
  console.log("IIFE"); }) ();Copy the code

This is where the commonly used “execute function expression now” format comes from.

Overall, we cannot be executed immediately “function declaration statement”, because there is an invisible semicolon, the function and represent the parentheses operator in the separation, and “function” is not this, so be executed immediately for a function declaration statement “, we have to put a “function declaration statement” with the “operator” recombination, Convert this to a “function expression”, hence the name “execute function expression now”.

Train of thought

In the same vein, we can use other “operators” to form a temporary “function expression” with the “function declaration statement” and then execute the function expression immediately to achieve immediate execution.

0.function () { console.log('IIEF') }();

+ function () { console.log('IIEF') }();
- function () { console.log('IIEF') }();
! function () { console.log('IIEF') }();

void function () { console.log('IIEF') }();
typeof function () { console.log('IIEF') }();
new function () { console.log('IIEF') }();
Copy the code

But in general, the above notation is rarely used, but the principle works.

conclusion

“Execute function expressions now” is used to simulate local scopes to achieve scope isolation. “Closures” and “execute module mode immediately” are extensions of this.

More and more

Follow my Github-day-Day-Up project for more articles

reference

Developer.mozilla.org/zh-CN/docs/… Softlab.sdut.edu.cn/blog/subaoc…