first, Preface
For JavaScript, closures are a very powerful feature. But it seems to be particularly advanced for beginners who have just begun to Contact. Today we come together to uncover the mystery of Closures. Closures This piece also has a lot of articles introduced, today I would like to talk about the closure of some of their understanding, hoping to provide a little meanness of insight to help the friends are Learning. The article can use colloquial I will try to use the colloquial narrative way, hoping to let readers better understand, after all, the article is written out the purpose is to let people read. There are inevitably shortcomings in the article and hope to help point Out.
second, the scope chain of Javascript
Before we learn about closures, let's look at a few things to Prepare.
Scope of the variable
first, what is a scope? domain, Zone. Simple to understand is the range (area) in which a variable can be accessed. In other words, the area where this variable can Work. According to this standard, we divide the variables 全局变量 into 局部变量 two kinds
The following characteristics are differentiated in a defined way:
Variables defined inside a function are local variables, and variables defined outside the function are global variables. (this is not just a feature of the Javascript Language) local variables can be accessed inside the function and cannot be accessed directly outside the function, so the local variable starts at the end of the function where it was defined. Of course There's a detail here-- 变量提升 . wait, Let's use a little bit of code to mention what the function promotion is. Let's take a look at the code for local variables and global variables
varA = 0;functiontestFunc () {varb = 1; Console.log ('-------------output-------------in function '); Console.log (a);//0Console.log (b);//1}//calling FunctionstestFunc (); Console.log ('-------------out-of-function output-------------'); console.log (a);//0Console.log (b);//uncaught referenceerror:b is not definedExecute the above code results as shown in
A B undefined exception was thrown in the last line of the code. that is, we do not access the local variables defined inside the function outside of the Function. But the normal output of the sixth line of code is visible inside the function we can access the global variable a defined outside the function
Variable declaration Promotion
Believe that if you learn C language, you should be very familiar with a sentence "first statement after use." This means that a variable or function must first find the declaration of the variable or function before using it. For example:
// C language correct wording int 0 ;p rintf (a); // wrong way, The following code can not be compiled by standard (direct reporting of EXCEPTIONS) printf (a); int 0;
Let's look at the Javascript code again.
var a = 0; Console.log (a); // Output Results 0
The above general wording we do not discuss, focus on the following code
Console.log (a); // Output result undefined var a = "hello"; console.log (a); // Output Result Hello
The operation results are as follows
The above example illustrates the feature of the variable declaration promotion, and we directly access the output of the variable a as undefined instead of directly reporting the exception before declaring the variable A. So the most intuitive feeling is that the declaration of the variable is promoted to the prior use. The code is essentially the Following:
var a; // the declaration was promoted here Console.log (a); // output undefineda = "hello"; console.log (a); // Output Result Hello
A recap
- Variables defined inside the function are local variables, and variables defined outside the function are global variables.
- Local variables cannot be accessed directly by the outside world, and global variables can be accessed within functions.
- Variable declaration Promotion
Scope characteristics of nested functions
To figure out the sum of the above, we're going to continue to explore another topic, nested functions in javascript, Let's start with a piece of code:
functionA (param) {varVara = 1; functionB () {varVarb = 2; Console.log ("----Function B----------") Console.log (vara);//Accessing the variables defined in the A function in function BConsole.log (param);//variables passed in a functionConsole.log (varb);//accessing a variable defined within its own function} B (); Console.log ("----Function A----------") Console.log (vara);//accessing a variable defined within its own functionConsole.log (param);//variables passed in a functionConsole.log (varb);//accessing variables defined in the B function--exceptions}a ("hello");The results of the operation are as Follows:
This shows that the nested function (b) can inherit the parameters and variables of the container function (A), but the variables in the nested function (b) are private to his container function, meaning that A cannot access the variables defined in B. In other words, the B function forms a relatively independent environment (space) so that its own variables can only be accessed by itself, but variable B in a function can also be accessed, where the nested function B forms a Closure. There's a very good word for B, "yours is mine, mine is mine."
The syntax is that function A contains function b, but from the scope it is the scope of function B that contains the scope of function A, as shown in the Relationship:
Assume that function B contains the function C below. At this point, function c is a nested function of function b, and function B is a container function of function C. For C also has just said "you are my, my or my" characteristics. And so on layer nesting, it forms a chain, the scope according to this law also forms the scope chain in Javascript.
three, the characteristics of closures
Let's start by summarizing the two points mentioned Above.
- Nested functions nested inside a container function (a) can be accessed only within the container function (a)
- The nested function (b) inherits the variables of the container function (a), but the variables in the B function are accessible only by itself, i.e. the scope of the nested function (b) contains the scope of the container function (a).
Save variables of closures
Let's start with a piece of code.
function a (a) { function B (b) { return A + B; } return B;} var C = A (1); var result = C (2); console.log (result); //
Function B forms a closure that returns a reference to function B after a function call. After executing C, we find that the result equals 3, which means that the parameter 1 that we passed in when we called A is not destroyed, but it is saved, which is the characteristic of the closure save Variable.
If there is a save, it will be destroyed. when do we destroy the variables that we have stored in closures? the answer is that when B is no longer referenced, it is Destroyed.
Closure note-naming Conflicts
Let's start with a piece of code.
function A () { var num = 6; external variable function B (num) { return num, named num; as the NUM variable passed in as a parameter, the naming conflict occurs in this }return B;} var result = A () (ten); console.log (result); // Output Results
The execution result of the above code
From the above code we can see a variable named num in a container function and a variable named num within a nested function. The result of this execution code takes precedence over the variables within the nested Function. Perhaps it is easier to remember this as a nearby Principle. This is the closure in the practical application of the point should be Noted.
Iv. application of closures in the development of the Package.
With regard to the use of closures in development, the most evident should be in the development of Javascript Plugins. Use closures to avoid variable Contamination. In other words, the variable name you use in the closure does not affect the same name elsewhere, and in other words, I have protected the variables inside my nested function, and there is no way to modify my internal definition arbitrarily. It's the same name, but you're you and Me. The code reflects the Following:
function A () { function B (num) { var c = ten; Internal variable c return num + c; } return B;} var c = 20; // external variable C var result = A () (c); console.log (c); // console.log (result)//
The above characteristics of the application in the plug-in development can be very good protection of the plug-in itself, to avoid the outside of the string change, to ensure the stability of the Plug-in.
Simple Plug-in
Preliminary code
// Writing Plug-in Code var plugin = (function() { function sayhi (str = ' hello! ') ) { console.log (str); } return Sayhi;}) (); // Use the plugin plugin (' hello ');p lugin ();
The above code closures section I'm not tired of saying, let's take a look at the new Syntax--call the anonymous function from:
(function{ //code}) ();
The actual effect is to create an anonymous function and execute it once when it is Created. The effect is equivalent to the following code, the only difference is that the following function is not anonymous.
// Create var function () { //code} // call func ();
Of course, We cannot write plugins that only provide an API for external use, and how to return multiple apis, which we use here in literal form. The code after the improvement is as follows
// Writing Plug-in Code var plugin = (function() { varfunction(str = ' hello! ') ) { console.log (str); } var function () { console.log ("this API can do very good things"); } return { sayhi: _sayhi, SayHello: _sayhello }}) (); // the API provided by the plugin uses the plugin plugin. Sayhi (' Hello ');p lugin. SayHello ();
Execution results
five, after the language
Today's view of closures is written here for the time being, adhering to the principle of application of knowledge, the next two articles I will introduce several development forms of JavaScript plug-ins, as well as practice-developing a native JavaScript plugin.
This article is the author original, reproduced please indicate the source!
A brief analysis of closures in JavaScript (Closures)