Execute function immediately

Together we think about it, if a js file declares a function inside a function a () {}, this function has not been call or be called but elsewhere and his references, then it has been in the memory of in the environment which it belongs (because the precompiled, promoted the) or refer to it in the scope of the function (closures, Unreleased), waiting to be called to execute or unable to be released, and is not destroyed until the entire file has been executed. Is there a function for initialization (which is executed once, only once)?

There are! Execute the function immediately!!

Definition:

A function that executes immediately and is destroyed immediately after execution

How to prove that it was destroyed immediately after execution?

(function abc() { console.log(123) }())  //123
console.log(abc)  //error:abc is not defined
Copy the code

ABC after execution, again access error, proof has been destroyed can not be found!

Similarities and differences with other functions:

Common: it can have arguments, it can have return values, it can have execution context, everything other functions have. Different: executed, immediately destroyed.

Examples with parameters

(function abc(a, b, c) { console.log(a + b + c) }(1, 2, 3))  //6
Copy the code

There are examples of return values

var num = (function abc(a, b, c) { return a + b + c }(1, 2, 3))
console.log(num) //6
Copy the code

Write the function immediately

(function(){}()) (function(){}())

On the difference between function declarations and function expressions

Function declaration (function (){}) and function expression (var a = function(){}). Only expressions can be executed symbols; function declarations cannot be executed, as shown in examples 1 and 2.

  1. Function declaration:
*** function test() {console.log(1)} () //error:Unexpected token ')'Copy the code
  1. Function expression:
*** var test = function test() {console.log(1) //1}()Copy the code

An expression executed by the executed symbol, which automatically abandons its function name (see examples 2 and 3).

* * * * * * example 3 var test = function () {the console. The log (1) / / 1} ()Copy the code

The expression executed by the executed symbol automatically abandons its function name, i.eThe expression executed by the executed symbolIt’s basically an immediate function! Look (Example 4) :

*** var test = function () {console.log(1) //1}() //error: test is not a functionCopy the code

But something that looks like a function declaration can be executed immediately, as in example 5

*** example 5*** +function test() {console.log(1)//1}() test()//error: test is not a functionCopy the code

Function test(){} is a function declaration, but it is preceded by a (+). This + tends to convert everything that follows to a number, so the test function is converted to a function expression by +. + has the same effect as (- and!) So don’t be completely fooled by definitions like function(){}.

Why is test undefined or an error?

*** example 6*** var test = function () {console.log(1)}() console.log(test) //undefined test()//error:test is not a functionCopy the code

Var test =function(){} =function(){} Function (){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function(){function();

Explain why wrapping () is a function expression?

Function (){})(function(){})(function(){})(function(){})(function(){})(function(){})(function(){}) Can we execute it? We can think about it mathematically, the role of alpha in mathematics. In (1+2)X2, () is a function symbol, and wrapped in () is a function expression. So it makes sense to look at it this way! Function (){}() {function(){}()); Function (){}() = function(){}() = function(){}() = function();

AD hoc (commas are also operators)

Function test(a, b, c, d) {console.log(a + b + c + d)} (1, 2, 3, 4Copy the code

This function does not comply with the expression can only be executed symbol execution, function declaration cannot be executed this clause, because this function is a function declaration then should report an error, but this function does not report error! But this function doesn’t execute either, so why? Because commas are also operators!! The system tries to avoid errors when executing. If, is the operator, the code will be parsed as follows:

Function test(a, b, c, d) {console.log(a + b + c + d)} (1, 2, 3, 4Copy the code

A common problem

Description: call a function with an array, add 10 items to it, each item is a method, execute the method, print the correct index of the array.

function test() {
    var arr = []
    for (var i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i)
        }
    }
    return arr
}
var myArr = test()
myArr[0]()
myArr[1]()
myArr[2]()
myArr[3]()
myArr[4]()
myArr[5]()
myArr[6]()
myArr[7]()
myArr[8]()
myArr[9]()
Copy the code

Write the code like this, but the result is 10 10s, not 0,1,2… 9. Think about why? Most of you probably know it’s a closure, but why print 10 tens?

MyArr [0]() = myArr[0]() This is just an execution of a function, taking something in its scope, so it’s not wrong there, it’s wrong in its scope. So where does his scope come from?

MyArr [0]() is scoped when it is defined, and creates its own OA when executed. When executed, his OA:{} has nothing, because there are no parameters and variables, and no function definitions. But remember that it stands on the shoulders of test. It inherits test’s OA, OA(test):{arr:[], I 😕 }. So what is this I? Let’s take a look at the implementation. The first cycle – > OA (test) : {arr: [function () {the console. The log (I)}], I: 0} second cycle – > OA (test) : {arr: [function () {the console. The log (I)}, unction () {the console. The log (I)}], I: 1} third cycle – > OA(test):{arr:[function(){console.log(i)},unction(){console.log(i)},function(){console.log(i)}],i:2} … Tenth loop -> OA(test):{arr:[function(){console.log(i)},unction(){console.log(i)},function(){console.log(i)},function(){console.log(i) },function(){console.log(i)},function(){console.log(i)},function(){console.log(i)},function(){console.log(i)},function() {console.log(i)},function(){console.log(i)}],i:9}

When myArr[0](), it prints I, but its own OA:{} is empty. If we follow the scope chain, we find the I in OA(test), which is already 10. So output 10 tens.


  1. If I = 0 arr[I]=arr[0] if I = 0 arr[0] =arr[0]
arr[i] = function () {
    console.log(i)
}
Copy the code

Function (){} is not called. It is only when the function is executed that it really looks inside and looks for I.


  1. Var myArr = test();test()Is OA(test) destroyed? How can we still find it?

Function (){console.log(I)}, function(){console.log(I)} this function has its own OA:{}, but remember that it stands on the shoulder of OA(test), OA(test) is referenced in its scope chain. So 10 new functions were created, each with a reference to OA(test).


Solution:

function test() {
    var arr = []
    for (var i = 0; i < 10; i++) {
        (function (j) {
            arr[j] = function () { 
                console.log(j)
            }
        }(i))
    }
    return arr
}
var myArr = test()
myArr[0]()
myArr[1]()
myArr[2]()
myArr[3]()
myArr[4]()
myArr[5]()
myArr[6]()
myArr[7]()
myArr[8]()
myArr[9]()
Copy the code

Inside the for loop, we write a function that executes immediately, OA(test):{arr:[function (j) {arr [j] = function () {console.log(j)}}], I :0} Function (){OA:{j:0}

Echo -> OA(test):{arr:[function (j) {arr [j] = function () {console.log(j)}} Function (j) {arr [j] = function () {the console. The log (j)}}], I: 1} function () {} OA: {1} j: [because j is parameter]

.

So when myArr0 is executed with j,j has on itself, then it is correct to get 0 ~ 9


  1. Where there’s a question, how do I get passed in?

I is passed as an argument to the immediately executed function


  1. The question is, how can arR [j] generate 10 items for arR within the immediate execution function?

Var arr = [] var arr = []; var arr = [];