Closure traps and cases you must know

Source: Internet
Author: User
Closure Insomelanguages, aclosuremayoccurwhenafunctionisdefinedwithinanotherfunction, andtheinnerfunctionreferstolocalvariablesoftheouterfunction...

Closure
In some versions, a closure may occur when a function is defined within another function, and the inner function refers to local variables of the outer function.
At run-time, when the outer function executes, a closure is formed, consisting of the inner function's code and references (the upvalues) to any variables of the outer function required by the closure.
 
Translation:
In some programming languages, closures occur: Another function is defined within a function, and internal functions reference local variables of external functions.
During running, when an external function is executed, a closure is formed, which consists of the code of the internal function and reference to any variable of the external function. This write reference depends on this closure.
// ECMAScript
Var f, g;
Function foo (){
Var x = 0;
F = function () {return ++ x ;};
G = function () {return -- x ;};
X = 1;
Alert ('inside foo, call to f (): '+ f (); // "2"
}
// External function execution, which forms a closure
Foo ();
// The x in foo is accessed only because of the closure.
Alert ('Call to g (): '+ g (); // "1"
// The x in foo is accessed only because of the closure.
Alert ('Call to f (): '+ f (); // "2"
 
 
Javascript closure traps and Cases
In many cases, because the internal function variables overwrite the closure variables, if we need to reference a variable with the same name as an external function, we need to execute an anonymous function, variables without external functions are passed in as parameters. As follows:
(Function (out_xxx ){
// You can use out_xxx
} (Xxx ))
We can see that the most common use of this method is when we define an object:
(Function (window ){
Var MyObject = function (){
This. initialize ();
}
Var p = DisplayObject. prototype;
P. initialize = function (){

}
Window. MyObject = MyObject;
} (Window ));
Defining an object in this way has two advantages:
1. Avoid contamination of external variables
2. PASS Parameters to reduce scope Lookup
Javascript has buried many pitfalls for us. In many scenarios, we need to use the above methods to solve the problem, which is listed below.
 
Scenario 1:
As shown below, I need to call the external name in the cc method:
Var bb, cc;
Function aa (){
Var name = "When Knight ";
Bb = function (){
Var name = "";
Cc = function (){
Var name = "Zhang Lei ";
Alert (name );
}
}
}
Aa ();
Bb ();
Cc (); // output "Zhang Lei"
Because the variables defined by the internal function overwrite the variables of the external function, the result is "Zhang Lei ".
Solution:
Var bb, cc;
Function aa (){
Var name = "When Knight ";
(Function (aa_name ){
Bb = function (){
Var name = "";
(Function (bb_name, aa_name ){
Cc = function (){
Var name = "Zhang Lei ";
Alert (aa_name );
Alert (bb_name );
Alert (name );
}
}) (Name, aa_name );
}
}) (Name );
}
Aa ();
Bb ();
Cc (); // output "When Knight", "brick house", and "Zhang Lei"
 
Real case:
I remember last week, one of my colleagues (interns) asked me about the following code. As follows:
$ ("# Dialog-form"). dialog ({
AutoOpen: false,
Height: 300,
Width: 350,
Modal: true,
Buttons :{
"Create an account": function (){
Var bValid = true;
AllFields. removeClass ("ui-state-error ");
BValid = bValid & checkLength (name, "username", 3, 16 );
BValid = bValid & checkLength (email, "email", 6, 80 );
BValid = bValid & checkLength (password, "password", 5, 16 );
If (bValid ){
$. Ajax ({
Type: "POST ",
Url: "xxxxx. aspx ",
Data: "name = xxxxx & email = xxxxx & password = xxxx"
}). Done (function (msg ){
Alert ("Data Saved:" + msg );
$ (This). dialog ("close ");
});
}
},
Cancel: function (){
$ (This). dialog ("close ");
}
},
Close: function (){
AllFields. val (""). removeClass ("ui-state-error ");
}
});
The dialog plug-in of JqueryUI is used here. See: http://jqueryui.com/demos/dialog/#modal-form

 

 

The result is to click create to initiate an asynchronous commit, and then close the pop-up layer during callback. What puzzles him is that the pop-up layer cannot be closed.
He complained:
Cancel: function (){
$ (This). dialog ("close ");
}
All cancel commands can be disabled. Why?
If (bValid ){
$. Ajax ({
Type: "POST ",
Url: "xxxxx. aspx ",
Data: "name = xxxxx & email = xxxxx & password = xxxx"
}). Done (function (msg ){
Alert ("Data Saved:" + msg );
$ (This). dialog ("close ");
});
}
Here $ (this). dialog ("close") Why cannot it be closed?
This is a typical scenario. solution:
If (bValid ){
(Function (outThis ){
$. Ajax ({
Type: "POST ",
Url: "xxxxx. aspx ",
Data: "name = xxxxx & email = xxxxx & password = xxxx"
}). Done (function (msg ){
Alert ("Data Saved:" + msg );
$ (OutThis). dialog ("close ");
});
}
} (This ))
},
 
Scenario 2 --- internal functions in a loop
Function TestObj (name ){
This. name = name;
}
Var objs = [];
Var obj;
Function test (){
For (var I = 0; I <100; I ++ ){
Var name = "Zhang Lei" + I;
Obj = new TestObj (name );
Obj. printName = function (){
Console. log (obj. name );
}
Objs. push (obj );
}
}
// External function execution and closure formation. The obj in the internal function obj. printName all points to the last new TestObj (name );
Test ();
// Output 100 times here ----- "Zhang Lei 99"
For (var I in objs ){
Objs [I]. printName ();
}
Solution
Function TestObj (name ){
This. name = name;
}
Var objs = [];
Var obj;
Function test (){
For (var I = 0; I <100; I ++ ){
Var name = "Zhang Lei" + I;
Obj = new TestObj (name );
(Function (target ){
Obj. printName = function (){
Console. log (target. name );
}
} (Obj ))
Objs. push (obj );
}
}
Test ();
For (var I in objs ){
Objs [I]. printName ();
}
 
Real case:
// Create and populate the screen with random daisies:
For (var I = 0; I <100; I ++ ){
Bitmap = new Bitmap (image );
Container. addChild (bitmap );
Bitmap. x = canvas. width * Math. random () | 0;
Bitmap. y = canvas. height * Math. random () | 0;
Bitmap. rotation = 360 * Math. random () | 0;
Bitmap. regX = bitmap. image. width/2 | 0;
Bitmap. regY = bitmap. image. height/2 | 0;
Bitmap. scaleX = bitmap. scaleY = bitmap. scale = Math. random () * 0.4 + 0.6;
Bitmap. name = "bmp _" + I;
// Wrapper function to provide scope for the event handlers:
(Function (target ){
Bitmap. onPress = function (evt ){
// Bump the target in front of it's siblings:
Container. addChild (target );
Var offset = {x: target. x-evt.stageX, y: target. y-evt.stageY };
// Add a handler to the event object's onMouseMove callback
// This will be active until the user releases the mouse button:
Evt. onMouseMove = function (ev ){
Target. x = ev. stageX + offset. x;
Target. y = ev. stageY + offset. y;
// Indicate that the stage shocould be updated on the next tick:
Update = true;
}
}
Bitmap. onMouseOver = function (){
Target. scaleX = target. scaleY = target. scale * 1.2;
Update = true;
}
Bitmap. onMouseOut = function (){
Target. scaleX = target. scaleY = target. scale;
Update = true;
}
}) (Bitmap );
}
This is a demo code on the Easeljs official website. Because internal functions are not executed immediately, when executing Internal functions that reference external function variables, this variable has been overwritten N times by the outer for loop, so we need to solve this problem through the above method.
 
Summary
This is a poor aspect of javascript. In addition to this, the getter and setter of javascript are also a depressing part of the syntax features of the language.
I believe that with the unremitting efforts of mankind, there will always be one day: static, namespace, interface, private, protected, class, enum • all can be javascript keywords, rather than a variety of techniques, all the articles corresponding to these keywords, notes, tips, and backdoors will sink the ground and never turn over. I believe that HTML5 was mature at that time. As chubby said: When do html5 game players no longer worry about js skills canvas performance optimization, it means html5 games are mature in this field.

From NAIT brick house --Iamzhanglei.com

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.