Variables and this objects in the JavaScript closure-Closure

Source: Internet
Author: User
In JavaScript, the scope chain mechanism can cause some side effects: the closure can only obtain the last value of any variable in the function. When using the closure, we must pay attention to the variable value problem, because this is a frequent error. In JavaScript, the scope chain mechanism can cause some side effects: the closure can only obtain the last value of any variable in the function. When using the closure, we must pay attention to the variable value problem, because this is a frequent error.

The following is a very extreme example to illustrate this problem. In actual development, we generally do not write code like this. The code for this example is as follows:

Function fn1 () {var arr = new Array (); // variable I is saved in the fn1 scope for (var I = 0; I <10; I ++) {arr [I] = function () {return I;} return arr;} var values = fn1 (); for (var I = 0; I <values. length; I ++) {// at this time, all the functions are called through the closure. When I is output, it will be searched in the scope of the upper level. At this time, the value of I is 10, therefore, 10 documents are output. write (values [I] () +"
");}

Execute the above Code. We expect to print 0-9 in the page, but 10 10 will actually be printed. Let's analyze this Code: The Implementation Code creates a function fn1, creates an array object in the function, assigns a value to the array through a for loop, and loops 10 times, each time an anonymous function is filled in the array, an array object is returned. Then, get the reference of the fn1 function, and output the values in the array through loops on the page.

The memory model of the scope chain of the above program is shown in:

We can see that every loop in the fn1 function will generate an anonymous function. They have their respective scopes, and their high scopes all point to the global scopes, the middle bit points to the fn1 scope of the outer layer, and the low bit points to its own scope.

After the fn1 function is executed, the value of attribute I in the fn1 scope is 10. GC starts to recycle fn1, But it finds that an anonymous function points to the fn1 scope, therefore, the fn1 scope will not be recycled.

When an anonymous function is executed, it searches for the property I in its own space, but does not find it, so it goes to its parent fn1 scope to find it. At this time, the I value in the fn1 scope is 10, so the anonymous function will get the same I value: 10.

To solve this problem, an anonymous function is returned in the anonymous function and the current value is saved through a variable. The Code is as follows:

Function fn1 () {var arr = new Array (); for (var I = 0; I <10; I ++) {arr [I] = function (num) {return function () {return num ;}} (I) ;}return arr ;}var values = fn1 (); for (var I = 0; I <values. length; I ++) {// each fs is in a different scope chain, and num is stored in different scopes. Therefore, 0-9 document is output. write (values [I] () +"
");}

In this case, the num value is stored in the scope of each anonymous function, and the value is exactly the same as the index value of each loop. In this way, when an anonymous function is called, it finds the num attribute in its own space, and the values of these num are different, at the same time, I attributes will not be searched in the fn1 function scope.

The above code will generate 20 anonymous function scopes. If the Code does not return a simple value, but some more complex operations, it will occupy a large amount of memory space.

This object in the closure

Using this object in closures also causes some unexpected problems. This object is bound to the function-based execution environment at runtime: for global functions, this object is window, and when a function is called as a method of an object, this is the object. In anonymous functions, this objects usually point to Windows. Let's take a look at the following example:

Var name = "window"; var person = {name: "Leon", age: 22, say: function () {return this. name ;}} console.info (person. say (); // console output: window

In the above Code, when we call the "say ()" method of the person object, what we print is not the name of the person object, but the global name "window ". When the person. after say (), the function is called. Before the function is called, this directs to person, but when an anonymous function is called, this points to window, the result is "window ".

To solve this problem, assign this reference to a temporary variable in the say () method. The Code is as follows:

Var name = "window"; var person = {name: "Leon", age: 22, say: function () {var that = this; return function () {return that. name ;}} console.info (person. say (); // console output: Leon

The above are the variables in the JavaScript closure-closure and the content of this object. For more information, see PHP Chinese website (www.php1.cn )!

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.