This article mainly analyzes a JS front-end closure interview question, and introduces the knowledge of JS front-end closure in detail from the example. If you are interested, you can refer to it.
Problem
Code
function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] } }}var a=fun(0);a.fun(1);a.fun(2);a.fun(3);var b=fun(0).fun(1).fun(2).fun(3);var c=fun(0).fun(1);c.fun(2);c.fun(3);
Find program output
This is a closure test question.
ConvertEquivalent code
The fun attribute of the returned object corresponds to a new function object, which forms a closure scope so that it can access Variable n of the outer function and the outer function fun, in order not to confuse the fun function and fun attribute, we modify the above Code as follows:
Code B
function _fun_(n,o){ console.log(o); return { fun:function(m){ return _fun_(m,n); } }}var a=_fun_(0);//undefineda.fun(1);//0a.fun(2);//0a.fun(3);//0var b=_fun_(0).fun(1).fun(2).fun(3);//undefined,0,1,2var c=fun(0).fun(1);//undefined,0,c.fun(2);//1c.fun(3); //1
So some people asked, why can we change it like this? How can you determine that fun in [1] is not fun in [2] Where code is located, you must know that the fun attribute here points to a function object ~
Here we will talk about the lexical scope of JS. The JS variable scope exists in the function body, that is, the function body, and the scope of the variable is determined when the function is declared, instead of running a function.
The following code
Var name = "global"; function foo () {console. log (name) ;}function fooOuter1 () {var name = "local"; foo () ;}fooouter1 (); // output global instead of local, function fooOuter2 () {var name = "local"; function foo () {console. log (name) ;}foo () ;}fooouter2 (); // output local instead of global. In the function declaration, the scope of the name variable is in its outer function. Well, it is the closure ~
Now let's go back to the question. In the definition stage of function declaration, the anonymous function at [2] is declared, and we found that a function object named fun needs to be referenced in [1, first, search for the function in the current function body. If no result is found, go to its outer function-the wrapped function of this anonymous function. If no result is found, go to the outer function, if no function package exists, go to the global environment and find it ...... specify the fun function as the fun function object in the global environment and add it to the closure of the anonymous function. Now we know why code B is equivalent to code ~~~
Create a closure Scope
After the lexical analysis, JS determines a closure, it is the closure of the anonymous function corresponding to the returned object fun property-the Internal Variable n for accessing the _ func _ and its outer function in the global environment;
During each _ func _ execution, the scope information of the variables in the closure is passed to the function execution environment for the function to obtain the variable value during execution.
Execution output
var a=_fun_(0);//undefineda.fun(1);//0a.fun(2);//0a.fun(3);//0
_ Fun _ FUNCTION execution, because the 2nd parameters are undefined, the output is undefined. Then, an object with the fun attribute is returned, pointing to a function object with a closure, which can access _ fun _ and Variable n _
A. fun (1) executes the fun method of the returned object, passes in the value of m 1, and calls the return value of _ fun)
Therefore, the output is 0, a. fun (2), a. fun (3), and a. fun (1)
Var B = _ fun _ (0). fun (1). fun (2). fun (3 );
Equivalent code:
Var B = _ fun _ (0 );
Var b1 = B. fun (1 );
Var b2 = b1.fun (2); // [3]
Var b3 = b2.fun (3); // [4]
The first two sentences are the same as the above output: undefined, 0. When [3] is called, the b1 object has a closure that references the _ fun _ function and the outer function variable n = 1, therefore, the function called by anonymous functions is _ fun _ (2, 1), the output result is 1, and a new object is returned.
When [4] is executed, the b2 object also has a closure that references the _ fun _ function and the outer function variable n = 2. Execute _ fun _ (3, 2) and the output result is 2.
var c=fun(0).fun(1);//undefined,0,c.fun(2);//1c.fun(3); //1
You can understand the previous Code Execution explanations and understand the above Code Execution output.