Most people will do wrong questions about the classic JS Closure

Source: Internet
Author: User

Most people will do wrong questions about the classic JS Closure

 

Interview Questions evolved from work

This is a problem I encountered at work. It seems very interesting. I went to the interview as a question and found that almost no one could answer all the correct questions and tell the reason. Let's have a chat.

First look at the question code:

Function fun (n, o ){
Console. log (o)
Return {
Fun: function (m ){
Return fun (m, n );
}
};
}
Var a = fun (0); a. fun (1); a. fun (2); a. fun (3); // undefined ,?,?,?
Var B = fun (0). fun (1). fun (2). fun (3); // undefined ,?,?,?
Var c = fun (0). fun (1); c. fun (2); c. fun (3); // undefined ,?,?,?

// Q: What are the outputs of three rows a, B, and c?

This is a very typical JS closure problem. Three Layers of fun functions are nested. It is particularly important to find out the fun function at each layer.

You can write down what you think on paper or elsewhere, and then expand to see what the correct answer is?

Answer

Are you correct? If you have all the correct answers, congratulations, there is almost nothing to block you in the js closure question. If there is no answer, continue the analysis.

JS has several functions

First, we need to know that functions in JS can be divided into two types,Name function)AndAnonymous Functions.

The method for distinguishing these two functions is very simple. You can judge by outputting fn. name. If there is a name, it is a name function. If there is no name, it is an anonymous function.

Note: In earlier versions of IE, the name of the function cannot be obtained and undefined is returned. We recommend that you test the function on Firefox or Google Chrome.

Or use the IE-compatible method to obtain the function name:

/**
* Get the name of the specified function for IE compatibility)
* @ Param {Function} Any Function of fun
*/
Function getFunctionName (fun ){
If (fun. name! = Undefined)
Return fun. name;
Var ret = fun. toString ();
Ret = ret. substr ('function'. length );
Ret = ret. substr (0, ret. indexOf ('('));
Return ret;
}

Use the above function to test whether the function is anonymous:

We can know that the variable fn1 is a named function, and fn2 is an anonymous function.

How to Create a function

After talking about the function types, you also need to know several methods to create functions in JS.

1. Declare a function

The most common and standard declaration function method, including the function name and function body.

Function fn1 (){}

2. Create an anonymous function expression

Create a variable whose content is a function

Var fn1 = function (){}

Note that the function created using this method isAnonymous FunctionsNo function name

Var fn1 = function (){};
GetFunctionName (fn1). length; // 0

3. Create a name function expression

Create a variable with a name.

Var fn1 = function xxcanghai (){};

Note: The name of a function expression can only be used inside the created function.

That is, the function created using this method can only use fn1 in the outer layer of the function and cannot use the xxcanghai function name. The xxcanghai name can only be used within the created function.

Test:

Var fn1 = function xxcanghai (){
Console. log ("in: fn1 <", typeof fn1, "> xxcanghai: <", typeof xxcanghai, ">") ;}; console. log ("out: fn1 <", typeof fn1, "> xxcanghai: <", typeof xxcanghai, "> ");
Fn1 ();

// Out: fn1 <function> xxcanghai: <Undefined>
// In: fn1 <function> xxcanghai: <function>

You can see that the function name of xxcanghai cannot be used outside the function, which is undefined.

Note: define functions in an object, such as var o = {fn: function (){...} }, Also belongs to the function expression

4. Function Constructor

You can pass a Function string to the Function constructor to return the Function that contains the string command.Anonymous Functions.

5. Self-executed Functions

(Function () {alert (1 );})();
(Function fn1 () {alert (1 );})();

The self-executed function belongs to the above "function expression" and has the same rules.

6. other methods for creating Functions

Of course, there are other methods to create or execute functions. I will not talk about them more here, for example, eval, setTimeout, setInterval, and other very useful methods. I will not introduce them too much here. This is a non-standard method.

What is the relationship between the three fun functions?

After talking about the function type and the method for creating the function, you can return to the topic and read this question.

This Code contains three fun functions, so the first step is to figure out the relationship between the three fun functions, which function is the same as the function.

Function fun (n, o ){
Console. log (o)
Return {
Fun: function (m ){
//...
}
};
}

First look at the first fun function, which is a standard named function declaration. YesNewIs an object literal expression, which belongs to a new object.

This new object contains an attribute also called fun. According to the above introduction, it is an anonymous function expression, that is, the property of fun storesNewAnonymous function expression.

Note: AllAll declared anonymous functions are new functions.

Therefore, the first fun function is different from the second fun function. They are all newly created functions.

Function scope chain problems

Before talking about the third fun function, let's talk about it first.Function expressionCan I access the variable that stores the current function internally.

Test 1. function expressions inside the object:

Var o = {
Fn: function (){
Console. log (fn );
}
};
O. fn (); // ERROR

Test 2. Non-object internal function expressions:

Var fn = function (){
Console. log (fn );
};
Fn (); // function () {console. log (fn) ;}; correct

The conclusion is: using var or a non-internal function expression of the object, you can access the variables that store the current function, but not inside the object.

The reason is also very simple, becauseFunction scope chainThe problem is that var is used to create a fn variable externally. Of course, the function can find fn internally and then search for fn in the scope of the previous book, because fn is not created in the function scope, it cannot be accessed.

Therefore, we can learn that,The innermost-layer return function is not the second-layer fun function, but the outermost fun function..

Therefore, the relationship between the three fun functions is also clear. The first is equal to the third, and they are not equal to the second.

Which function is being called?

Let's look at the original question again. Now we know that there are two fun functions in the program (the first and the third are the same). The next question is to find out which fun function is executed during runtime?

Function fun (n, o ){
Console. log (o)
Return {
Fun: function (m ){
Return fun (m, n );
}
};
}
Var a = fun (0); a. fun (1); a. fun (2); a. fun (3); // undefined ,?,?,?
Var B = fun (0). fun (1). fun (2). fun (3); // undefined ,?,?,?
Var c = fun (0). fun (1); c. fun (2); c. fun (3); // undefined ,?,?,?

// Q: What are the outputs of three rows a, B, and c?

1. First Line

Var a = fun (0); a. fun (1); a. fun (2); a. fun (3 );

We can know that the first fun (0) is calledFirst-level fun Functions. The second fun (1) is the fun function that calls the return value of the previous fun, so:

The last few fun (1), fun (2), and fun (3) functions are called.Second-level fun Functions.

Ui:

When fun (0) is called for the first time, o is undefined;

When fun (1) is called for the second time, m is 1. At this time, fun closures the n of the outer function, that is, n = 0, that is, m = 1, n = 0, and internally call the first level of fun function (); so o is 0;

M is 2 when fun (2) is called for the third time, but a is still called. fun, so the n of the first call is closed, so the first layer of fun (2, 0) is called internally, so o is 0.

The fourth time is the same;

That is, the final answer is undefined, 0, 0

2. Row B

Var B = fun (0). fun (1). fun (2). fun (3); // undefined ,?,?,?

First, from fun (0), it must be the first level of fun function called; and its return value is an object, so the second fun (1) the second-level fun function is called, and the second-level fun function is called later.

Ui:

When the first level of fun (0) is called, o is undefined;

The second call. when fun (1), m is 1. At this time, fun closures the n of the outer function, that is, the n = 0 called for the first time, that is, m = 1, n = 0, and internally call the first level of fun function (); so o is 0;

M is 2 for the third call. fun (2). At this time, the current fun function is not the returned object for the first execution,Returned object for the second execution. In the second execution of the first layer of the fun function (), so n = 1, o = 0, the second n is closed when the return value is, then when the third layer of the fun function is called, m = 2, n = 1, that is, the first layer of fun function fun (2, 1) is called, so o is 1;

For the fourth call. fun (3), m is 3, and n of the third call is closed. Similarly, the first-layer fun function is called (3, 2), so o is 2;

That is, the final answer: undefined, 0, 1, 2

3. Row c

Var c = fun (0). fun (1); c. fun (2); c. fun (3); // undefined ,?,?,?

Based on the previous two examples, we can see that:

Fun (0) is used to execute the first level of fun function ,. fun (1) executes the second-layer fun function returned by fun (0). The statement ends here. Then c stores the returned value of fun (1), instead of fun (0) so the closure in c is also the value of n for the second execution of fun (1. C. fun (2) executes the second-level fun function returned by fun (1) and c. fun (3 ).AlsoIs the second-level fun function returned by fun (1.

Ui:

When the first level of fun (0) is called, o is undefined;

The second call. when fun (1), m is 1. At this time, fun closures the n of the outer function, that is, the n = 0 called for the first time, that is, m = 1, n = 0, and internally call the first level of fun function (); so o is 0;

The third call. when fun (2) is used, m is 2. At this time, the fun closure is the n = 1 of the second call, that is, m = 2, n = 1, and internally call the first level of fun function (2, 1); so o is 1;

The fourth time. fun (3) is the same, but it is still the second return value of the call. Then, the first layer of fun function fun (3, 1) is finally called, so o is 1

That is, the final answer: undefined, 0, 1, 1

Remarks

This code was originally used to write an asynchronous callback into a synchronously called component. It found this pitfall and gained a deeper understanding of the closure of JS.

There are countless articles on the Internet about what a closure is, but to understand what a closure is, you must discover and comprehend it yourself in the code.

If I want to talk about a closure, I think that a closure in the broad sense means that a variable is used in its own scope and is called a closure.

I hope that you will have a better understanding of the closure phenomenon through this article. If you have any other opinions or opinions, please correct me or leave a message to discuss it.

End)

In-situ http://www.cnblogs.com/xxcanghai/p/4991870.html

If you believe that this article is worthy of the time you have spent reading it, click the recommendation in the lower right corner. Thank you.

Author: xiaojinghai
Source: http://www.cnblogs.com/xxcanghai/
Address: http://www.cnblogs.com/xxcanghai/p/4991870.html

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.