[Cson original] analyzes an uncommon trap and an uncommon Technique in JS closures.

Source: Internet
Author: User

An uncommon closure trap:

 VaR  Test1  =  {Name:  '  Cson  '  };
VaR Name = ' Noname ' ;
With (Test1 ){
Function Setname (){
Name = ' Xiaoc ' ;

}
Setname ();

}

Alert (test1.name );
Alert (name );

We often see a description similar to this in the document: With opens the object closure, and sets the attribute and method in the object closure to add attributes and methods for the object. According to this understanding, the above results should be: 'xiaoc 'and 'noname '.

However, the experimental results are 'cson' and 'xiaoc '. (Ie chrome) 'xiaoc 'and 'noname' (Firefox ).

Analysis:

In fact, it is not perfect to say that setting attributes and methods in the with object closure is equal to adding attributes and methods to the object. The exception is that when the closure of nested functions in the object closure is, in this case, apart from Firefox's approval of the above sentence, ie and chrome will use another method for processing.

We know that JavaScript has two runtime cycles: the parsing cycle and the execution cycle. When processing the above process, Firefox and IE chrome adopt different processing methods:

Firefox considers:The declaration in the object closure and the object closure itself (that is, it is treated as the property of test1). Therefore, setname is created as a method property of test1, so the name processed in it is the name attribute of test1.

However, ie and chrome think:The declaration in the object closure should not work with the object closure. In the parsing cycle of JS, since with has not yet worked, they resolve the setname declaration to the global closure domain, and then make setname and with the "same level ", therefore, the name set in setname becomes the global name variable.

Solution:

To sum up, we only need to change the function declaration in the object closure into a value assignment, so that IE and chrome can avoid parsing setname in the global closure during the JS parsing cycle.

FunctionSetname (){
Name= 'Xiaoc';

}

Change

 
VaRSetname=Function(){
Name= 'Xiaoc';

}

In this way, the "Declaration" is changed to "value assignment", and all browser engines process the function in the execution cycle of Js.

After modification, the output of Firefox ie Chrome is 'xiaoc 'and 'noname'

An uncommon technique about closures:

You should be familiar with the classic issue of this closure:

   <  Div  ID  = "A0"  >  A0  </  Div  >  
< Div ID = "A1" > A1 </ Div >
< Div ID = "A2" > A2 </ Div >
< Div >
   Function  Test2 (){
For ( VaR I = 0 ; I < 3 ; I ++ ){
Document. getelementbyid ( ' A ' + I). onclick = Function () {Alert (I );}
}
}
Test2 ();

The result is that after the three elements of A0 A1 A2 are clicked, the alert value is 3, because the closure makes them use the same I value.

The classic solution is: 

 Function Test2 (){
For ( VaR I = 0 ; I < 3 ; I ++ ){
( Function (){
VaR J = I;
Document. getelementbyid ( ' A ' + I). onclick = Function () {Alert (j );}
})();
}
}
Test2 ();

However, this poses a problem. Only external DOM elements do not release the reference, and the closure causes the variable objects on the entire scope chain to be stored in the memory, resulting in performance loss, is there a better way to solve this problem without using closures?

A better method is as follows: 

    Function  Test2 (){
For ( VaR I = 0 ; I < 3 ; I ++ ){

(Document. getelementbyid ( ' A ' + I). onclick = Function () {Alert (arguments. callee. J);}). j = I;

}
}
Test2 ();

It cleverly solves the problem by setting custom attributes for the function without using closures.

Reference books: javascript advancedProgramDESIGN: javascript language essence and programming practices

Welcome to reprint, please indicate the source: http://www.cnblogs.com/Cson/archive/2011/03/31/2001631.html

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.