# 1 JavaScript functions allow you to access variables defined outside the function
If you know the concept of JavaScript's scope chain, it's not hard to understand this one.
In a word, JS looks for the definition of a variable from the nearest area, and the local area is not found.
Until you find the top of the namespace, the Window object is at the top of the browser's world.
| The code is as follows |
Copy Code |
Example-1 var a_var_in_global_environment = "Hello Closure" function func () { Console.log (a_var_in_global_environment) } Func () Hello Closure Example-2: function Func2 () { var var_in_function = "I ' m a var in function"; return function () { Console.log (a_var_in_global_environment + "--and--" + var_in_function); } } Func2 () () Hello Closure--and--I ' m a var in function |
# 2 Even if the external function has returned, the internal function can still remember the variables defined by the external function
It sounds a little weird, but it's the same.
Take our example-2 above, the value returned by Func2 is a function (which is also called a higher order function), and this function is not executed immediately.
, and this function holds almost all the parameters and variable information within the scope of the function, even if the external function returns, it still remembers,
Remember.
So, the function that holds the variable in its scope can be called a closure
# # 3 Closures can update values of external variables
what can I do with a closure?
the answer to this question may surprise you--you can do anything with the closures. As far as I know, closures allow ECMAScript to imitate anything, so the limitation lies in the ability to design and implement things to imitate. It's just that it's literally a bit esoteric, so let's take a look at some more practical examples.
Example 1: Setting a delay for a function reference
A common use of closures is to provide arguments for the function to be executed before the function is executed. For example, the function is used as the first parameter of the Settimout function, which is a very common application in the context of a Web browser.
SetTimeout is used to systematically execute a function (or a string of JavaScript code, not in this case), the function to be executed is its first argument, and the second parameter is the execution interval in milliseconds. That is, when you use settimeout in a piece of code, you take a reference of a function as its first argument, and the time value in milliseconds as the second argument. However, passing a function reference cannot provide arguments for a function that is scheduled to execute.
However, you can call another function in your code, which returns a reference to the intrinsic function, and then passes the reference to the internal function object to the SetTimeout function. The parameter to use when executing this intrinsic function is passed when the call returns its external function. In this way, settimeout does not pass arguments when executing this intrinsic function, but the intrinsic function still has access to the arguments passed when the call returns its external function:
| code is as follows |
copy code |
| function Calllater (Parama, Paramb, PARAMC) { /* Returns a reference to an anonymous intrinsic function created by a function expression:-*/ Return (function () { /* This internal function will pass-settimeout-Execute, and when it executes, it reads and follows the Arguments to external functions: Www.111cn.net / Parama[paramb] = PARAMC; }); } ... |
/* Calling this function returns a reference to the internal function object created in its execution environment.
The parameters passed will eventually be used as arguments to the external function by the intrinsic function.
The reference to the intrinsic function returned is assigned to a global variable:-
*/
var functref = Calllater (Elstyle, "display", "none");
/* Call the SetTimeout function, which will be assigned to the variable-functref-
The reference to the intrinsic function of the is the first parameter passed:-* *
Hidemenu=settimeout (Functref, 500);
Example 2: Associating functions with object instance methods
Back to Top
Many times we need to hang a function object temporarily to a reference for later execution, because it is difficult to know the specific parameters of the execution, and it was not even known when the reference was previously assigned to it. (This section is translated by Pangba Liu Weipeng)
(Luyy friend's translation _2008-7-7 update) Many times you need to assign a function reference, in order to execute the function at some point in the future, it would be useful to provide parameters to the function when they are executed, but they are not easy to obtain when executed, and they are only determined when they are assigned to them.
(Original note: There are many circumstances when a reference to a function object are assigned so this it would be executed at Some future time where it's useful to provide parameters for the execution of this function that's would not be easily Ava Ilable at the time of execution but cannot is known until the moment of assignment.)
A related example is the use of JavaScript objects to encapsulate interaction with a particular DOM element. This JavaScript object has Doonclick, Domouseover, and Domouseout methods and is executed when the user triggers the corresponding event in that particular DOM element. However, it is possible to create any number of JavaScript objects associated with different DOM elements, and each object instance does not know how the code that instantiates them will manipulate them (that is, the registration event handler is separated from the definition of the corresponding event handler function). Translator note). These object instances do not know how to reference themselves in the global environment, because they do not know which global variable (if any) will be specified to refer to their instance.
Thus the problem can be attributed to executing an event handler that is associated with a particular JavaScript object, and knowing which method to call the object.
The following example uses a generalized function based on a closure build (this sentence is more Shei pointing), this function associates an object instance with a DOM element event, schedules the specified method of the object instance to be invoked when the event handler is executed, and the parameter passed by the specified method of the image is the event object and the reference associated with the element. This function returns the return value after the corresponding method is executed.
| The code is as follows |
Copy Code |
| /* A function of an associated object instance and event handler. The internal functions it returns are used as event handlers. Object instances are represented by-obj-parameters, The name of the method invoked in the object instance is represented by a-methodname-(string) parameter. */ function associateobjwithevent (obj, methodname) { /* The following internal function returned as an event handler for a DOM element Return (function (e) { /* In browsers that support the standard DOM specification, event objects are parsed as parameters-e-, If there is no normal parsing, the event object is normalized using IE's event objects. */ E = e| | window.event; /* Event handler called object by method name saved in string-methodname- -Obj-a method. and passes the already normalized event object and the element that triggers the event handler Reference-this-(the reason this is valid is because the intrinsic function is executed as the method of the Element) */ Return Obj[methodname] (e, this); }); } /* This constructor is used to create an object that associates itself with a DOM element. The ID of the DOM element acts as a string argument to the constructor. The object created will trigger the onclick in the corresponding element, onmouseover or onmouseout event, Call the appropriate method. */ function Dhtmlobject (elementid) { /* Calls a function that returns a reference to the DOM element, if no return null is found. The required parameter is an ID. Assigns the returned value to the local variable-el-. */ var el = Getelementwithid (ElementID); The/*-El-value is converted internally into a Boolean by type conversion, so that the-if-statement is judged. Therefore, if it references an object, the result returns true and False if it is null. The following code block is executed only if the-el-variable returns a DOM element. */ if (EL) { /* Specifies a function for the event handler for the element that invokes the -Associateobjwithevent-function. At the same time, the object takes itself (through-this-keyword) as the object that invokes the method, and provides the name of the method invoked. -Associateobjwithevent-function returns An intrinsic function that is specified as the event handler for the DOM element. When responding to an event, executing the internal function invokes the necessary method. */ El.onclick = Associateobjwithevent (This, "Doonclick"); El.onmouseover = Associateobjwithevent (This, "domouseover"); El.onmouseout = Associateobjwithevent (This, "domouseout"); ... } } DhtmlObject.prototype.doOnClick = function (event, Element) { ...//Doonclick method body. } DhtmlObject.prototype.doMouseOver = function (event, Element) { ..///Domouseover method body. } DhtmlObject.prototype.doMouseOut = function (event, Element) { ..///Domouseout method body. } |
Thus, any instance of Dhtmlobject associates itself with the corresponding DOM element, and these DOM elements do not have to know how other code manipulates them (that is, what code is executed when the corresponding event is triggered). Also ignore the impact of the global namespace and the risk of conflict with other instances of Dhtmlobject.
Example
| The code is as follows |
Copy Code |
| A few useful examples Closed-Pack uniqueid************* UniqueID = (function () {//The invocation object of this function holds the value var id = 0; That's the value of the private eternity. The outer function returns a nested function that has access to a constant value That's the nested function we keep in the variable UniqueID. return function () {return id++;}; return, self added. })(); Call the outer function after the definition. Document.writeln (UniqueID ()); 0 Document.writeln (UniqueID ()); 1 Document.writeln (UniqueID ()); 2 Document.writeln (UniqueID ()); 3 Document.writeln (UniqueID ()); 4 Closed Bao Jie by ************* var a = (function (n) { if (n<1) {alert ("Invalid arguments"); return 0;} if (n==1) {return 1;} else{return n * Arguments.callee (n-1);} }) (4); Document.writeln (a); function User (properties) { Here you must declare a variable to point to the current instance var objthis = this; for (var i in properties) { (function () { In the closure, T is new every time, and the value of Properties[i] is for the var t = properties[i]; objthis[' get ' + i] = function () {return t;}; objthis["Set" + i] = function (val) {t = val;}; })(); } }
Test code var user = new User ({ Name: "Bob", Age:44 });
Alert (User.getname ()); Alert (User.getage ());
User.setname ("Mike"); Alert (User.getname ()); Alert (User.getage ());
User.setage (22); Alert (User.getname ()); Alert (User.getage ()); |