A brief talk on JS closure and the This keyword

Source: Internet
Author: User

Problem background: Because of the existence of the closure in JS and the particularity of this, it is often impossible to determine the value of the variable.

A Variables in closures

Example 1.

  1. var name= "thewindow";
  2. var getname= (function () {
  3. var name = "My function";
  4. return function () {
  5. return name;
  6. }
  7. })();
  8. Console.log (GetName ()); //my function
  9. Console.log (name); The Window
  10. Getname=null; Remove the reference to the anonymous function and release the excess memory occupied by the closure

The concept of closure in JS is that closures are functions that have access to variables in another function scope.

In Example 1, the getname right-hand function expression is an immediate execution function and returns an anonymous function, which is a closure. For a normal function, it will release its occupied memory after execution, but it is not the case for closures. GetName is the anonymous function returned, which is useful to the name of an external anonymous function, so immediately after execution of the function is not free of memory, it must be determined that the closure can not be executed again in case the memory is freed (the reason that the closure consumes a lot of memory).

Why CODE5 's name is parsed into my function and Code10 is parsed into the window?

This will be said from the execution environment (execution context, commonly known as "contexts"), when the code executes in the execution environment, first create the variable object, and then create a variable object (VO) a scope chain, to ensure that the execution environment has access to all variables and functions of the orderly access. The front end of the scope chain is always a variable object in the execution environment where the code is currently executing, and the next variable object comes from the next variable object that contains the execution environment, which continues to the Global Execution Environment (window). The parsing of identifiers is also parsed from the front end of the scope chain (the VO of the current execution environment) to the end of the scope chain (VO for the Global Execution Environment). It is important to look at the scope of the variable, as long as it is in the scope chain of the execution environment where it resides. ------Because the function execution environment is special, its variable object is called the active object (AO). The global execution environment is special, and its variable objects always exist!

Executes GetName (), where name is the scope chain of the execution environment (the closure function execution environment) that contains itself (that is, the closure function) of the active object, the outer function (that is, the immediate execution function) of the active object, the global variable object, the search from inside Out, and the name definition from the External function activity object. Executes Console.log (name), where name is the scope chain of the execution environment (global execution Environment) that contains only global variable objects from which the name definition is found.

Example 2.

  1. var result = [];
  2. function Createfunctions () {
  3. For (var i=0; i<3; i++) {
  4. Result[i]=function () {
  5. return i;
  6. };
  7. }
  8. }
  9. Createfunctions ();
  10. Console.log (Result[0] ()); //3
  11. Console.log (Result[1] ()); //3
  12. Console.log (Result[2] ()); //3

This configuration mechanism of the scope chain causes closures to only get the last value of any variable that contains the function!

Workaround:

  1. var result = [];
  2. function Createfunctions () {
  3. For (var i=0; i<3; i++) {
  4. Result[i]= (function (num) {
  5. return function () {
  6. return num;
  7. };
  8. }) (i);
  9. }
  10. }
  11. Createfunctions ();
  12. Console.log (Result[0] ()); //0
  13. Console.log (Result[1] ()); //1
  14. Console.log (Result[2] ()); //2

Use 3 immediate functions to give each function () {return num}, make a closure, save a copy of I into NUM, and have a copy of 3 I, respectively, 0,1,2,result[i] to take the corresponding copy.

Extension: Since there is no concept of block scope in JS, you can use the immediate execution function to make block scopes through the mechanism of closures!

Example 3.

    1. /*JS no block-level scope causes local variables to affect global variables */
    2. i=2;
    3. for (var i=0;i<4;i++) {}
    4. alert (i); //4

Example 4.

    1. /* Use the immediate execution function to mimic block-level scopes with the closure mechanism, without affecting the external variables */
    2. i=2;
    3. (function () {
    4. for (var i=0;i<4;i++) {}
    5. })();
    6. alert (i); //2

Two The particularity of this

Let's start with a simple example:

Example 5.

  1. var name= "thewindow";
  2. var object = {
  3. Name: "My Object",
  4. GetName:function () {
  5. var name = "My Function";
  6. return this . Name
  7. }
  8. }
  9. Console.log (Object.getname ()); //my Object
  10. Console.log ((Object.getname) ()); //my Object
  11. Console.log ((object.getname = Object.getname) ()); //the Window

This is based on the execution environment binding: In the global function, this refers to the window; When the function is called as an object method, this refers to the object;

Code10 and Code11 the same way, better understanding. (Note: this. is the attribute, var name= "My function" in getname cannot be understood to add a property to the function name and the value of the property is "my function"!) )

Code12 people may be more confused, why not output "My object"?

    1. Console.log ((object.getname = Object.getname) ()); //the Window

(Object.getname = object.getname) The meaning of this function expression is:

1. Set the GetName property/method for object.

2. Assign the value of Object.getname to it

3. Therefore the value of the expression is the function itself: functions () {var name = "My funcition"; return this.name;}

Equivalent to:

    1. Console.log (function () {var name = "My function"; return this.name;}) ()); //the Window

Global function, this is window, so this.name is "the window"!

Example 6.

  1. var name= "thewindow";
  2. var object = {
  3. Name: "My Object",
  4. GetName:function () {
  5. return function () {
  6. return this . Name
  7. };
  8. }
  9. }
  10. Console.log (Object.getname ()); //the Window
  11. Console.log ((object.getname = Object.getname) () ()); //the Window

anonymous function is special, this refers to window! ;

The classification of the comparison system is in the language of JavaScript, which is divided into function invocation pattern (This binding Global object window) and method invocation pattern (the body of the this binding called method).

It can be seen that when a function is used in a function call pattern, this is actually fixed to window! (as shown in Code11), this is actually a JS language design flaw, if the language design is correct, it should be: when the internal function is called, the inner function of this should be bound to the external function this object!

This design flaw has an easy solution:

  1. var name= "thewindow";
  2. var object = {
  3. Name: "My Object",
  4. GetName:function () {
  5. var = this ;
  6. return function () {
  7. return that. name;
  8. };
  9. }
  10. }
  11. Console.log (Object.getname ()); //my Object
  12. Console.log ((object.getname = Object.getname) () ()); //the Window

Assign the This object to the variable that, so that the closure can be taken to the external variable that (note: Each execution environment has its own this, so you have to use this method to get the external this object)

Example 7

  1. var name= "thewindow";
  2. Getname= (function () {
  3. var name = "My function";
  4. return function () {
  5. var name= "function";
  6. return this . Name
  7. }
  8. })();
  9. Console.log (GetName ()); //the Window
  10. Console.log ((GetName) ()); //the Window

Finally, check:

Code11 and Code10 are the same, code10 belong to function calls, so this refers to window

A brief talk on JS closure and the This keyword

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.