The variable closure of a closed packet in JS and this

Source: Internet
Author: User

Closures and variables:

A side effect of the scope chain, the closure can only get the last value that contains any variable in the function. Don't forget that the closure holds the entire variable object, not a particular variable.

function fn1 () {//Create an array        vararr =NewArray (); //an array assignment, at which I is saved in the scope of the FN1         for(vari =0; I <Ten; i++) {Arr[i]=function () {returni}}returnarr; }   varFS =fn1 ();  for(vari =0; i < fs.length; i++) {fs[i] (); //at this time by the closure to call the function, will go to the first-level scope of the search, which is the value of I is already 10, so it will be output 10 consecutive ten;};

WORKAROUND: Force the behavior of the closure to conform to expectations by creating another anonymous function

function fn1 () {vararr =NewArray ();  for(vari =0; I <Ten; i++) { arr[i] = (function (num) {return function () {return num;  }}) (i); There are a large number of scopes at this time }returnarr; }   varFS =fn1 ();  for(vari =0; i < fs.length; i++) {fs[i] (); //This is 0,1,2,3,4,5,6,7,8,9,};

Consumes a lot of memory,

This problem with closures:

The use of this object in closures can also cause problems where the This object is bound at run time based on the execution environment of the function:
In the global function, this equals window, and when the function is called as a method of an object, this is equal to that object. However, the execution environment of an anonymous function is global, so its this object usually points to window.

var name = "A";    var object = {        "obj",        function() {            return function () {                returnthis. Name;}}   }   Object.say () ();   // at this point, the output is a,
When Object.say () is called, the function memory space of object is freed, but the inside of the closure is still there, and this is the point to the window

Workaround:

 var  name = "A" ;  var  object = {name:  "obj" , say:  function   () { 
   
    // 
     at this point it points to object  
    var  
    that  = this  ;  return  function   () { return   that . Name; }}} 
Object.say () ();  At this point, the output is obj,
Leakage of Memory:

If an HTML element is stored in the scope chain of the closure, it means that the element will not be destroyed.

function Assignhandler () {
var element = document.getElementById ("someelement");
Element.onclick = function () {
alert (element.id);
};
}

A closure is created as an element event handler, and the anonymous function holds a reference to the active object of Assignhandler (), as long as the anonymous function exists and the reference number of element is at least 1, so it
The memory that is occupied is never recycled. can be resolved by slightly rewriting the code,

function Assignhandler () {        var element = document.getElementById ("someelement");         var id = element.id;         function () {            alert (ID);        };         NULL ;  }

Save a copy of the element.id in a variable, and reference the variable in the closure to eliminate the circular reference. This step alone will not resolve the memory leak. Closures refer to include functions
The entire activity object, which contains element. Even if the closure does not directly refer to element, a reference is still saved in the active object that contains the function. Therefore, it is necessary to set the element variable to null.

Block-level scope:

JavaScript does not have the concept of block-level scope, whether it is after the use of loops or judgments, this variable will always exist, so when the global use of the loop or judgment, this variable may affect the function of the variable, so unless special circumstances, do not use global variables, and global variables at the top of the scope chain, The slowest access,

 for (var i = 0; i < ten; i++) {        };  alert (i);   At this time I is ten;

The workaround is an anonymous function, which is the syntax for an anonymous function that is used as a block-level scope (often called a private scope) as follows.

(function() {    // This is a block-level scope    });

Defines and immediately invokes an anonymous function. In a large application involving many developers, too many global variables and functions can easily lead to naming conflicts. By creating a private scope, each developer can
To use your own variables without worrying about messing up the global scope.
This approach reduces the memory problems that are used by closures because there are no references to anonymous functions. As soon as the function is executed, its scope chain can be destroyed immediately.

Private variables:

Private variables include arguments to functions, local variables, and other functions defined inside the function.

function Add (NUM1, num2) {    var sum = num1 + num2;     return  3 Private variables: NUM1, num2, and Sum. These variables can be accessed inside the function, but they cannot be accessed outside the function. If a closure is created inside the function, the closures can also access the variables through their own scope chain. 

Public methods that have access to private variables and private functions are called privileged methods (privileged method).

 function   person (name) { //  Privileged method  this . SetName = function   = value;  //  Privileged method  this . getName = function   () { Span style= "color: #0000ff;"    >return   name;   }}  var  p = new  person ("Linda");   P.setname ("Joke"); P.getname (); // joke  

Two Privileged methods: GetName () and SetName (). Both of these methods can be used outside the constructor, and both have access to the private variable name. But outside of the person constructor, there is no way to access name.
They can be used as closures to access name through the scope chain. The private variable name is not the same in every instance of person, because each call to the constructor will recreate both methods.
The disadvantage of the constructor pattern is that the same set of new methods are created for each instance, and the use of static private variables to implement privileged methods avoids this problem.

Static private variables:

Finding more than one level in the scope chain can affect the search speed to some extent. And that's one obvious disadvantage of using closures and private variables.

Module mode

Module mode can be enhanced by adding private variables and privileged methods to the singleton.

varSingleton = (function(){    //private variables and private functions    varPrivatevariable = 10; functionprivatefunction () {return false; }    //Privileged/Public methods and properties    return{publicproperty:true, Publicmethod:function() {privatevariable++; returnprivatefunction (); }    } })();
This module mode uses an anonymous function that returns an object. Inside the anonymous function, private variables and functions are defined. The returned object literal contains only properties and methods that can be exposed. Because this object is defined inside an anonymous function , its public methods have access to private variables and functions. This one
The object literal defines a singleton public interface. This pattern is useful when you need to perform some initialization of a singleton, while maintaining its private variables:
 varApplication = (function(){    //private variables and functions    varcomponents =NewArray (); Components.push (Newbasecomponent ()); //Public    return{getcomponent:function(){            returncomponents.length; }, RegisterComponent:function(component) {if(typeofComponent = = "Object") {Components.push (component); }        }    } })();

You can use module mode if you must create an object and initialize it with some data, and also expose some methods to access the private data. Each singleton created in this mode is an instance of Object,

Enhanced Module Mode:

This enhanced module pattern is suitable for cases where the singleton must be of a certain type, while some properties and/or methods must be added to enhance it.

varSingleton = (function(){    //private variables and private functions    varPrivatevariable = 10; functionprivatefunction () {return false; }    //Creating Objects    varObject =NewCustomtype (); //Add privilege/public properties and MethodsObject.publicproperty =true; Object.publicmethod=function() {privatevariable++; returnprivatefunction ();    }; //return This object    returnobject;}) ();
Summarize:

function expressions are different from function declarations. A function declaration requires a name, but the function expression does not need it. A function expression without a name is also called an anonymous function.
Recursive functions should always use Arguments.callee to call themselves recursively, and do not use function names, which may vary.


When other functions are defined inside a function, a closure is created. The closure has access to all variables inside the function, and the principle:

The scope chain of a closure contains its own scope, the scope of the containing function, and the global scope.

The scope of the function and all of its variables are destroyed at the end of the function execution.

When a function returns a closure, the scope of the function is persisted in memory until the closure does not exist. Using anonymous functions can mimic block-level scopes in JavaScript (JavaScript itself does not have the concept of block-level scopes), as in the following.

? Create and call a function immediately so that you can execute the code in it without leaving a reference to the function in memory.
? The result is that all variables inside the function are immediately destroyed-

Closures can also be used to create private variables in objects, and the concepts and key points are as follows.
? Even though there is no formal concept of private object properties in JavaScript, you can use closures to implement public methods, and you can access the variables defined in the containing scope through public methods.
? Public methods that have access to private variables are called privileged methods.
? You can use the constructor pattern, prototype mode to implement a custom type of privileged methods, or you can use module mode, enhanced module mode to implement a single-instance privileged method.

function expressions and closures in JavaScript are extremely useful features that can be used to implement many functions. Because creating closures must maintain additional scopes, excessive use of them can consume a lot of memory.


The variable closure of a closed packet in JS and this

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.