"JavaScript" javascript closures

Source: Internet
Author: User

Before describing the implementation and use of closures, you need to understand some of the following knowledge points.

Execution context (execution context) 

1 console.log (a);     //  23 console.log (b);    // undefined 4 var b; 5 6 Console.log (c);    // undefined 7 var c = 10;

Looking at an example above, when a direct output of a in the console, a is not defined, this is easy to understand. However, when the values "var B" and "var C = 10" were executed before the output of B and C, the result was undefined. Since the code is executed in one line, "Var B" and "var C = 10" must not be executed until Console.log () is executed. And the result is different from the output of a, what's the matter?

Second case:

1 console.log (this);

Output:

The third case:

1  Console.log (F1);   2function F1 () {}; // function Declaration 3 4 Console.log (F2); 5 var function  (){}; // function Expression

Output:

As can be seen here, in a section of JS code to get a real sentence before running, the browser did some "preparation", including the declaration of the variable, not the assignment, the variable assignment is performed at the time of the assignment statement, and the function of the Declaration of the assignment. The function expression is similar to var C = 10 In the first case, and the result is the same. Of course there is the assignment of this and so on.

Here's a summary of what the browser does in preparation:

Variable, function expression--variable declaration, the default assignment is undefined;

this--Assignment Value

function declaration--Assignment

The readiness of these three kinds of data we call "execution context" or "execution context".

All of this is done in a global environment.

In the function, in addition to the above data, there will be other data.

1 function f (x) {2    console.log (arguments); 3     Console.log (x); 4 }5 F (10);

Output:

The code above shows that the parameters of the arguments variables and functions have been assigned before the statement execution of the function body.

Thus we can see that each time a function is called, a new execution context is generated. Because different invocations may have different parameters.

Further, when the function is defined (not when it is called), the scope of the free variable inside the function body is determined.

To summarize:

The context data contents of the global code are:

Common variables (including function expressions),

such as: var a = 10;

Declaration (default assignment is undefined)

function declaration,

such as: function fn () {}

Assign value

This

Assign value

If the code snippet is a function body, you need to attach it on this basis:

Parameters

Assign value

Arguments

Assign value

Value scope of free variables

Assign value

Give the execution context a common definition-- before executing the code, all the variables that will be used are taken out beforehand, some are directly assigned, and some are first empty with undefined.

When executing the JS code, there are countless number of function calls, resulting in a number of context contexts. How can so many contexts be managed and how can it be destroyed to free up memory? This introduces a concept-the execution context stack .

Here's a concept-- this.

In peacetime, this frequency is very high, we will use it in many cases. Regardless of where you get this, there is a value. The exact value of this in the function is determined when the function is actually called and the function definition is not. Because the value of this is part of the execution context, each time a function is called, a new execution context is generated.

Next, the value of this is described in four scenarios:

  Scenario 1: Constructors

The so-called constructor is the function that is used for the new object. In fact, strictly speaking, all functions can be new, but some functions are defined for new objects, while others are not. Also note that the function name of the constructor is capitalized (the rule Convention) in the first letter. For example: Object, Array, function, and so on.

If the function is used as a constructor, then this represents the object it is about to be new. Here is a case where the function's call is not a new object, but rather a direct call to the function, where the value of this is window.

Here's another question, in the prototype of the constructor, what this represents. It is not just the prototype of the constructor, even in the entire prototype chain, this represents the value of the current object.

  Scenario 2: Function as a property of an object

If the function is a property of an object and is called as a property of an object, this point in the function points to the object.

  Scenario 3: function is called with call or apply

When a function is called by call and apply, the value of this takes the value of the passed-in object.

  Scenario 4: Global & Call normal function

In a global environment, this is always a window, and when the normal function is called, this is also the window.

Continue learning the context stack below.

When executing the global code, an execution context is generated, and each invocation of the function results in an execution context. When the function call is complete, the context and the data in it are eliminated and then back to the global context. There is only one execution context environment that is active. This is actually a stack out of the process-the execution context stack.

In the context stack, there is only one active context in the same time.

When a function is called, a new execution context is generated and pressed into the execution context stack, the original stack top execution context goes inactive, and the newly pressed execution context enters the active state.

When the function call is complete, the stack top execution context is popped up and destroyed by the recycle mechanism, while the new stack top context goes into active state.

However, this is an ideal operation, sometimes the execution context does not say that destruction will be destroyed, this is the following--closures.

Scope & Scope Chain

In any programming language, there is a concept of scope. In JavaScript, in addition to the global scope, only the scopes that the function can create. The scope is determined when the function is defined. Instead of being determined when the function is called.

So, when we declare a variable, the global code is declared at the front of the code, and the function is declared at the beginning of the function body. In addition to these two places, there is no declaration of variables anywhere else. It is also recommended to use the form "single Var". Because in a function, if you declare a variable without "var", the variable being declared is a global variable.

A scope is a very abstract concept, similar to a "site", such as:

The scope has a subordinate relationship, the determination of the subordinate relationship is to see where the function is created under the scope. For example, when the bar function is created under the FN scope, the FN scope is the ancestor of the bar scope.

The most useful use of scopes is to isolate variables, and there will be no conflicts between variables of the same name in different scopes.

We combine scopes with contextual contexts, such as:

  

In, we can see that the scope is just a "site", an abstract concept, where there are no variables. The value of the variable to get from the execution context environment corresponding to the scope. Under the same scope, different invocations produce different execution contexts, which in turn produce values for different variables. Therefore, the value of a variable in the scope is determined during execution, and the scope is determined when the function is created.

So, if you want to find the value of a variable under a scope, you need to find the execution context in which the scope corresponds, and then look for the value of the variable.

Here is a concept-the free variable. The so-called "free variable", the variable that is called in this scope, is not declared in this scope, but a variable declared in the other scope, which is called a "free variable".

When we call a free variable in this scope, where do we go to get the value of the variable? Some would say that the parent scope to this scope is called. This is a bit vague and sometimes ambiguous. correctly, it should be: to get the value in the scope where the function was created--"create", not "call". In fact, this is called the "static Scope".

What is described above is just a cross-step scope to look for.

What if it's a step that hasn't been found yet? --Then cross! --continues across the global scope. If it's not found in the global scope, it's really gone.

This step-by-step "cross" route, as we call it, is a chain of scopes.

Let's describe the process in words: (Suppose A is a free variable)

In the first step, now the current scope looks for a, if any, gets and ends. if not, continue;

The second step, if the current scope is a global scope, proves that a is undefined, ends; otherwise continues;

The third step, (not the global scope, which is the function scope), will create the scope of the function as the current scope;

Fourth step, jump to the first step.

And then there's the main course-- closures .

With regard to closures, Baidu's explanation is that closures are blocks of code that can contain variables that are free (not bound to specific objects), that are not defined within this block of code or in any global context, but are defined in the context in which the code block is defined (local variables) ... It looks a little foggy.

In fact, we just need to understand the application of the two cases--function as the return value, the function as a parameter passed.

function as the return value:

1 functionfn () {2     varA = 10;3     4     functionBar (x) {5         if(X <a) {6             Console.log (X);7         }8     }9     Ten     returnBar; One}

  The function is passed as a parameter:

1 var 2max = 10;3fn =function(X) {4          if(X >max) {5 Console.log (X);6          }7          Else{8 Console.log (max);9          }Ten      };  One  A(function(f) { -      varmax = 100; -F (15); the}) (FN);

The output here is: 15. The reason for taking Max's value is to fetch it from the scope that created the function, not the "parent scope." So the value is 10, not 100.

Combining the previous studies, we can take a look at the following picture:

In the diagram we can see that the FN () call is complete after line 17th is executed. It is supposed to destroy the execution context of FN (), but this cannot be done here. Note that the emphasis is on: Because a function is returned when the FN () is executed. The special thing about functions is that you can create a separate scope. And coincidentally, in the body of the returned function, there is also a free variable Max to refer to in the FN () context under the FN scope. Therefore, this max cannot be destroyed, and Max in the bar function will not be able to find the value after destroying it. Therefore, the FN () context here cannot be destroyed and still exists in the execution context stack.

Executes to line 20th, executes F1 (15), that is, executes bar (15), creates a bar (15) context, and sets it to the active state.

When you execute bar (15), Max is a free variable and needs to be found in the scope where the bar function was created, and the value of Max is 10. The point is that creating a bar function is created when you execute FN (). FN () has long been executed, but the FN () execution context still exists with the stack, so when bar (15), Max can find it. If the FN () context is destroyed, then Max cannot find it. Thus the FN context is still not destroyed in the stack.

Although the use of closures increases memory consumption, and improper use may cause a memory leak problem, but there are many uses. For example, anonymous self-executing functions, anonymous self-executing functions, implementing encapsulation, and implementing object-oriented objects, the traditional object language provides a template mechanism for the class, and so on.

"JavaScript" javascript closures

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.