http://www.nowamagic.net/librarys/veda/detail/1707 the scope chain and variable objects are described earlier, it is easy to understand the closure now. Closures in fact, everyone has been talking rotten. Still, it's a theory to try to discuss the closure from a theoretical point of view, and see how the closures inside the ECMAScript work.
It is still necessary to take a look at some basic definitions of functional programming before discussing ECMAScript closures directly.
As is well known, in functional languages (ECMAScript also supports this style), functions are data. For example, a function can be assigned to a variable, it can be passed to other functions, it can be returned from a function, and so on. This type of function has a special name and structure.
Defined
A functional argument ("Funarg")-is an argument which value is a function.
The function parameter ("Funarg")--is the argument that the value is a function.
Example:
function Examplefunc (funarg) { funarg ();} Examplefunc (function () { alert (' Funarg ');});
The actual parameters of Funarg in the above example are actually anonymous functions passed to Examplefunc.
Conversely, functions that accept function arguments are called higher-order functions (High-order function Abbreviation: HOF). It can also be called a function function or a partial mathematical or an operator. In the above example, Examplefunc is such a function.
Previously mentioned, functions can be used as parameters as well as return values. Such functions as return values of functions are called functions with function values (functions with functional value or function valued functions).
(function functionvalued () { return function () { alert (' returned function is called ');}} ) ()();
Functions that can exist in the form of normal data (for example, when a parameter is passed, a function parameter is accepted, or returned as a function value) are referred to as the first class of functions (typically, the first class object). In ECMAScript, all functions are the first class of objects.
Functions can exist as normal data (for example, when a parameter is passed, a function parameter is accepted, or returned as a function value), it is called the first class of function (typically the first class object).
In ECMAScript, all functions are the first class of objects.
A function that accepts its own parameters, called self-applied functions (auto-applicative function or self-applicative function):
(function selfapplicative (funarg) { if (funarg && funarg = = = selfapplicative) { alert (' Self-applicative '); return; } Selfapplicative (selfapplicative);}) ();
Functions that return values by themselves are called self-replicating functions (auto-replicative function or self-replicative function). In general, the word "self-copying" is used in literary works:
(function selfreplicative () { return selfreplicative;}) ();
One of the more interesting patterns of self-replicating functions is to allow only one item of the collection to be accepted as a parameter instead of accepting the collection itself.
function Registermodes (modes) { Modes.foreach (Registermode, modes) that accepts the collection;} Usage registermodes ([' roster ', ' accounts ', ' groups ']);//Declaration function modes (mode) { Registermode (mode) Register a mode return modes;//return function itself}//usage, modes chain call modes (' roster ') (' accounts ') (' groups ')// Somewhat similar: Jqueryobject.addclass ("a"). Toggle (). Removclass ("B")
But the direct collection is relatively effective and intuitive.
Variables defined in a function parameter are accessible when "Funarg" is activated (because the variable object that stores the context data is created each time it enters the context):
When function Testfn (funarg) { ///Funarg is active, local variable localvar can access Funarg (ten); //Funarg ( Function (ARG) { var localVar = ten; Alert (arg + LocalVar);});
However, in ECMAScript, a function can be encapsulated in a parent function and can use a variable of the parent function context. This feature can cause funarg problems.
Funarg problems
In a stack-oriented programming language, local variables of a function are stored on the stack, and each time the function is activated, the variables and function arguments are pressed onto the stack.
When the function returns, these parameters are removed from the stack. This model has a large limit on the use of functions as function values (for example, return values are returned from the parent function). In most cases, the problem arises when the function has free variables.
A free variable is a variable that is used in a function but is not a function parameter or a local variable of a function.
Example:
function Testfn () { var localVar = ten; function Innerfn (innerparam) { alert (Innerparam + LocalVar); } return INNERFN;} var somefn = Testfn (); Somefn (20); 30
In the above example, for the INNERFN function, the Localvar is a free variable.
For a system that uses a stack-oriented model to store local variables, it means that when the TESTFN function call is finished, its local variables are removed from the stack. In this way, an error occurs when a function call is made externally to INNERFN (because the Localvar variable is no longer present).
Furthermore, in the case of the stack implementation model, the above example is not possible to return the INNERFN to the return value at all. Because it is also a local variable of the TESTFN function, it will also be removed as the TESTFN returns.
Another problem is that when the system uses a dynamic scope, the function is used as a function parameter.
See the following example (pseudo code):
var z = 10;function foo () { alert (z);} Foo (); 10– when using static and dynamic scopes (function () { var z =; Foo (); 10– uses a static scope, 20– uses dynamic scope});//the same time as foo as a parameter (function (funarg) { var z = +; Funarg (); 10– static scope, 30– dynamic scope}) (foo);
We see that systems with dynamic scopes, variables (identifiers) are managed through variable dynamic stacks. Therefore, the free variable is queried in the dynamic chain that is currently active, rather than in the static scope chain that is saved when the function is created.
This creates a conflict. For example, even if z is still present (contrary to the example of removing a variable from the stack), there is still a question: in different function calls, what is the value of Z (from which context, which scope is queried)?
The two types of funarg problems are described above--depending on whether the function is returned with a return value (the first type of problem) and whether the function is used as a function parameter (the second type of problem).
In order to solve the above problems, the concept of closure is introduced.
Closed Package
Closures are a combination of code blocks and data in the context in which the code block is created.
Let's take a look at the following example (pseudo code):
var x = 20;function foo () { alert (x);//Free variable "x" = = 20}//for foo closure fooclosure = { Call:foo//reference to function Lexica Lenvironment: {x:20}//Context of the search context};
In the above example, the "Fooclosure" section is pseudo-code. Correspondingly, in ECMAScript, the "foo" function already has an intrinsic property--the scope chain that creates the function context.
"Lexical" is usually omitted. The above example is to emphasize that the context data will be saved while the closure is being created. The next time the function is called, the free variable can be found in the saved (closed) context, as shown in the code above, and the value of the variable "z" is always 10.
The more generalized term we use in the definition-"code block", however, usually (in ECMAScript) uses the functions we often use. Of course, not all implementations of closures will tie closures and functions together, for example, in the Ruby language, closures can be a process object (procedure object), a lambda expression, or a block of code.
The stack-based implementation is obviously not applicable (because it contradicts the stack-based structure) for the implementation to persist the local variables after the context is destroyed. Therefore, in this case, the closure data for the upper scope is implemented by dynamically allocating memory (based on the "heap" implementation), with the garbage collector (garbage collector referred to as GC) and the reference count (reference counting). This implementation is less than the performance of a stack-based implementation, however, any implementation can always be optimized: You can analyze whether a function uses free variables, functional arguments, or functional values, and then decide depending on the situation-whether the data is stored on the stack or in the heap.
Extended Reading
The list of topics for this article is as follows:
- How do we know how the JavaScript engine works
- JavaScript Quest: The importance of writing maintainable code
- JavaScript Quest: Use global variables with caution
- JavaScript Quest: Var pre-parsing and side effects
- JavaScript Quest: For Loop (for Loops)
- JavaScript Quest: For-in loop (for-in Loops)
- JavaScript Quest: Prototypes is too powerful
- JavaScript Quest: eval () is "the Devil"
- JavaScript Quest: Using parseint () for numeric conversions
- JavaScript Quest: Basic Coding Specifications
- JavaScript Quest: function declaration and function expression
- JavaScript Quest: Named function expressions
- JavaScript Quest: Function names in the debugger
- JavaScript Quest: Bugs in JScript
- JavaScript Quest: Memory management for JScript
- JavaScript Quest: SpiderMonkey's Quirks
- JavaScript Quest: Named Function expression substitution scheme
- JavaScript Quest: Objects Object
- JavaScript Quest: Prototype chain Prototype chain
- JavaScript Quest: Constructor Constructor
- JavaScript Quest: Executable Context Stack
- Execution context One: Variable object and active object
- Execution context Second: scope chain scope Chains
- Execution context its three: closure Closures
- Execution context Its four: this pointer
- JavaScript Quest: Powerful prototypes and prototype chains
- One of the JavaScript functions: function declaration
- JavaScript functions second: function expressions
- JavaScript functions three: function expressions in Groups
- JavaScript functions its four: function constructors
- JavaScript variable object one: VO's declaration
- JavaScript Variable Object second: Vo in different execution contexts
- JavaScript Variable Object Three: Two stages of the execution context
- JavaScript Variable object four: about variables
- JavaScript variable object Its five: __parent__ property
- JavaScript scope chain One: scope chain definition
- JavaScript scope chain Second: The life cycle of a function
- JavaScript scope chain Three: scope chain characteristics
- JavaScript closures: An introduction to closures
- JavaScript closures Second: implementation of closures
- JavaScript closure Three: the use of closures
JavaScript closures First: Closure Introduction some basic definitions of functional programming