JS closure, scope chain, garbage collection, memory leak related knowledge summary _javascript skills

Source: Internet
Author: User
Tags closure garbage collection memory usage variable scope

Add:

Closures (closure) are a difficult and unique feature of the JavaScript language, and many advanced applications rely on closure implementations.

Characteristics of closures

Closures have three features:

1. Function Nesting function

2. Functions can refer to external parameters and variables inside

3. Parameters and variables will not be recycled by garbage collection mechanism

Definition of closure and its advantages and disadvantages

Closures are functions that have access to variables in the scope of another function, and the most common way to create closures is to create another function within one function and access the local variables of the function through another function.

The drawback of closures is resident memory, which increases memory usage, and can easily lead to memory leaks due to improper use.

Closures are a major feature of JavaScript language, and the main applications of closures are designed to: design private methods and variables.

After the normal function is finished, the local active object is destroyed and only the global scope is saved in memory. But the closures are different!

Start a topic around a topic

1. What is the definition of closures?

Take a look at some definitions of closures:

1. Closures refer to functions that have access to variables in another function's scope

2. Function objects can be linked by the scope chain, and the variables within the function body can be stored within the scope of the function, which is called the ' closure '.

3. Internal functions can access parameters and variables that define their external functions (except this and arguments).

We want the system to learn the concept of JS closures can refer to cloud-Habitat community website js ebook column to learn it.

To define a summary

1. Functions that can access variables in the scope of an external function

2. Variables of external functions accessed by internal functions can be stored within the scope of an external function without being recycled---this is the core, we have to think of the closure, we have to focus on the variable referenced by the closure.

To create a simple closure.

var sayname = function () {
var name = ' Jozo ';
return function () {
alert (name);
}
};
var say = Sayname (); 
Say ();

To interpret the following two statements:

var say = Sayname (): Returns an anonymous internal function stored in the variable say, and references the variable name of the external function, because the garbage collection mechanism, after the completion of the Sayname function, the variable name has not been destroyed.

say (): performs the returned internal function, still accesses the variable name and outputs ' Jozo '.

2. The scope chain in the closure

Understanding the scope chain is also helpful for understanding closures.

Variables in the scope of the lookup method should be very familiar with, in fact, this is the scope of the chain to look up.

When a function is invoked:

1. First create an execution environment (execution context), and the corresponding scope chain;

2. Add the values of arguments and other named parameters to the active object of the function (Activation object)

Scope Chain: The active object of the current function has the highest priority, the external function is followed by the active object, and the external function's external functions are sequentially decremented to the end of the scope chain-global scope. Priority is the order of variable lookup;

Let's look at a common scope chain:

function Sayname (name) {return
name;
}

This piece of code contains two scopes: a. Global scope; The scope of the B.sayname function, that is, only two variable objects, when executed to the corresponding execution environment, the variable object becomes the active object and is pushed into the front-end of the execution environment scope chain, which is the highest priority. Look at the illustrated words:

This figure is also in the JS Advanced programming book, I have redrawn.

When you create the Sayname () function, creates a scope chain that contains a predetermined variable object, the scope chain indexed to 1 in the diagram, and is saved to the internal [[Scope]] property, and when the Sayname () function is invoked, an execution environment is created and then copied by copying the function's [ [Scope]] property, and then an active object (index 0 in the figure) is created and pushed into the front-end of the execution environment's scope chain.

In general, when the function completes, the local active object is destroyed, and only the global scope is saved in memory. However, closures are also different:

Let's look at the scope chain of closures:

function Sayname (name) {return
function () {return
name;
}
}

This closure instance has more scope for an anonymous function than the previous example:

After the anonymous function is returned from the Sayname () function, its scope chain is initialized to the active object and the global variable object that contains the Sayname () function. In this way, anonymous functions can access all the variables and parameters defined in Sayname (), and more importantly, the Sayname () function will not be destroyed after execution, because the scope chain of the anonymous function still references the active object, in other words, sayname () When the function finishes executing, the scope chain of its execution environment is destroyed, but his active object stays in memory, knowing that the anonymous function will be destroyed. This is also the issue of memory leaks to be mentioned later.

Scope chain problems I don't write so much, I'm tired of writing books. O (╯-╰) o

3. Examples of closures

Example 1: Implementing Cumulative

Mode 1
var a = 0;
var add = function () {
a++;
Console.log (a)
}
Add ();
Add ();
Mode 2: Closure
var add = (function () {
var a = 0;
return function () {
a++;
Console.log (a);
}
}) ();
Console.log (a); Undefined
Add ();
Add ();

In contrast, Mode 2 is more elegant, and also reduces global variables, privatizing variables

Example 2: Add a Click event to each Li

var oli = document.getelementsbytagname (' li ');
var i;
for (i = 0;i < 5;i++) {
Oli[i].onclick = function () {
alert (i);
}
}
Console.log (i); 5
//Execute anonymous function
(function () {
alert (i);//5
} ());

The above is a classic example, we all know that the execution result is to pop 5, also know can use the closure to solve this problem, but I just started not to understand why every pop-up is 5, why the closure can solve this problem. Then smoothed it out or made it clear:

A. First to analyze the situation before the closure: in the For loop, we bind an anonymous function to each Li Click event, return the value of the variable i in the anonymous function, and when the loop is over, the value of the variable I becomes 5, and then we click on each Li, which is to execute the corresponding anonymous function (see above code), This is the variable I already is 5, so each click POPs up 5. Because every anonymous function returned here is a reference to the same variable i, if we create a new variable to save the current value of I when the loop executes, then let the anonymous function apply this variable, and then return to the anonymous function, so that we can achieve our goal, this is the use of closures to achieve!

B. To analyze the application of closures in the following cases:

var oli = document.getelementsbytagname (' li ');
var i;
for (i = 0;i < 5;i++) {
Oli[i].onclick = (function (num) {
var a = num;//To illustrate the problem return
function () {
al ERT (a);
}
}) (i)
}
Console.log (i); 5

When the For loop executes, the anonymous function to which the Click event is bound is passed I immediately executes to return an internal anonymous function, because the parameter is passed by value, then parameter num holds the value of the current I and assigns it to local variable a, and then the internal anonymous function keeps a reference to the That is, the value of the current I is kept. So after the loop has finished clicking each Li, the returned anonymous function executes the value of the reference of the respective saved a.

4. Closure of the application

Let's look at the closure's purpose. In fact, we can do a lot of things by using closures. For example, simulate object-oriented code style, more elegant, more concise expression of code, in some ways to improve the efficiency of code execution.

1. Anonymous self-execution function

We often encounter situations in which a function needs to be executed once and its internal variables need not be maintained, such as the initialization of the UI, so we can use closures:

Changes all Li fonts to Red
(function () { 
var els = document.getelementsbytagname (' li ');
for (var i = 0,lng = Els.length;i < lng;i++) {
els[i].style.color = ' red ';
} 
}) ();

We created an anonymous function and executed it immediately, because external variables cannot be referenced within it, so els,i,lng these local variables will be released soon after execution, saving memory!

The key is that this mechanism does not pollute the global object.

2. Implementation of encapsulation/modular code

The Var person= function () { 
//variable scope is inside the function, and the 
var name = ' Default ' cannot be accessed externally; 
return { 
getname:function () {return 
name 
}, 
setname:function (newName) { 
name = NewName; 
} 
} 
} ();
Console.log (person.name)/direct access, the result is undefined 
console.log (Person.getname ());//default 
Person.setname ( "Jozo"); 
Console.log (Person.getname ()); Jozo

3. Implementing objects in an object-oriented

Such different objects (instances of the class) have independent members and states, Non-interference. Although there is no such mechanism in JavaScript, we can simulate such a mechanism by using closures. Or in the example above:

function person () { 
var name = ' Default '; 
return { 
getname:function () {return 
name 
}, 
setname:function (newName) { 
name = newname;< c26/>} 
} 
; 
var person1= person (); 
Print (Person1.getname ()); 
John.setname ("Person1"); 
Print (Person1.getname ()); Person1 
var person2= person (); 
Print (Person2.getname ()); 
Jack.setname ("Erson2"); 
Print (Erson2.getname ()); Person2

Two instances of person person1 and person2 do not interfere with each other! Because these two instances are independent of the access to name this member.

5. Memory Leaks and solutions

Garbage collection mechanism

When it comes to memory management, the garbage collection mechanism of JS can not be separated from, there are two kinds of policies to realize garbage collection: Mark Clear and reference count ;

Mark Clear: The garbage collector marks all variables stored in memory when it is run, and then it removes the markup of the variables in the environment and the tokens of the variables referenced by the variables in the environment, and then, if the variable is marked again, the variable is ready to be deleted. By 2008, Ie,firefox,opera,chrome,safari's JavaScript had been used in this way;

reference count: tracks the number of times each value is referenced, and when a variable is declared and the value of a reference type is assigned to the variable, the value is 1, and if the value is assigned to another variable, the reference number plus 1. Conversely, if a variable is divorced from a reference to that value, the value reference is reduced by 1, and when the number is 0 o'clock, the garbage collector's collection is awaited.

A big problem with this approach is circular references, which means that a object contains a pointer to B, and object B also contains a reference to a. This can result in a large amount of memory not being recycled (memory leaks) because they can never be referenced 0 times. The early IE version (IE4-IE6) uses a counting garbage collection mechanism, one of the reasons the closure causes memory leaks is a flaw in the algorithm.

We know that some of the objects in IE are not native JavaScript objects, for example, the objects in the BOM and Dom are implemented as COM objects, and the garbage collection mechanism of COM objects uses reference counting. Therefore, although IE's JavaScript engine uses the tag purge policy, accessing COM objects is still based on reference counting, so as long as you design COM objects in IE there is a circular reference problem!

Give me a chestnut:

Window.onload = function () {
var el = document.getElementById ("id");
El.onclick = function () {
alert (el.id);
}

Why does this piece of code cause memory leaks?

el.onclick= function () {
alert (el.id);

When executing this code, the anonymous function object is assigned to the OnClick property of El, and the El object is referenced inside the anonymous function, and there is a circular reference, so it cannot be reclaimed;

Workaround:

Window.onload = function () {
var el = document.getElementById ("id");
var id = el.id; Loop reference
El.onclick = function () {
alert (ID); 
}
el = null; Clear the active object in the external function referenced by the closure
}

The above is a small series to introduce the JS closure scope chain garbage collection memory leakage related knowledge summary, I hope to help!

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.