The concept of closures

Concept: A combination of a function bound (or surrounded by) references to its surrounding state (lexical environment) is a closure. That is, closures allow you to access the scope of an outer function within an inner function. In JavaScript, whenever a function is created, the closure is created at the same time the function is created.

Simple to understand: a data structure that binds environment information to owning information during the declaration of a function. Such as:

function test(){
    const a =  10;
    return function fn(){
        console.log(a); }}const myfn = test();
myfn(); / / 10
Copy the code

The fn function above can access the a constant in the scope of the test function. Here is a typical closure.

scope

Closures occur in relation to the scope of js. Js scope is mainly divided into two types: 1, global scope. 2. Local scope.

  • Global scope: that is, variables in the global scope will be used, js global variables will be hung on the window global object. Such as:
<script>
  var a = 10;
	console.log(a);  / / 10
	console.log(window.a); / / 10
</script>
Copy the code
  • Local scope: The scope in which a variable has an effect on the local scope.

    • Function scope, you can use a function to make a variable only have a local scope, for example:

       function test(){
         	// Function scope variables are only used inside functions
              var a = 10;
              console.log(a);
          }
       test(); / / 10
       console.log(a); // a is not defined
      Copy the code
    • Scope chain: According to the mechanism by which internal functions can access external function variables, a chain lookup to determine which data can be accessed by internal functions is called a function scope chain. The scope-chain lookup principle is the proximity principle.

      function fn1 (){
              var num = 10;
              function fn2(){
                 var num = 20;
                  function fn3(){
                      console.log(num);
                  }
                  fn3();
              }
              fn2();
          }
        fn1();
      Copy the code

      The above code num looks up the upper scope, and if it doesn’t find the num variable, it continues to look up the upper scope, forming a scope chain.

    • Block-level scope: The scope at work in the “{}” code block. Such as:

      {
              // Variables only work within the "{}" code block
              let  a = 10;
              console.log(a);
      }
      console.log(a);  // a is not defined
      Copy the code

    closure

    Because the declaration of a function binds the environment information to its owning information, as reflected in the scope chain above, the closure is formed by preserving references to parent objects in the function scope. Some advanced functions in JS can be implemented with closures.

    • Distinguish scope

      • Local scope can be distinguished by function scope and closure property to prevent variable contamination

        (function (){
                var a = 10;
                function test(){
                    console.log(a); 
                }
                test(); / / 10}) ()console.log(a); // a is not defined
        Copy the code
    • Make internal variables accessible to outsiders

      function test(){
              var a = 10;
              return function(){
                  console.log(a); }}let testFn = test();
       testFn();
      Copy the code

      The above code can access the a variable inside test, and the test function is also a higher-order function. Higher-order functions: Functions that take another Function as an argument are called higher-order functions.

    • The cache feature

      • You can use closures to cache variables, for example:
      const once = (fn) = >{
          let done = false;
          return function(){
              if(! done){ fn.apply(this,fn);
              }else{
                  console.log("this fn is already execute");
              }
              done = true; }}function test(){
          console.log("test...");
      }
      let myfn =  once(test);
      myfn();  // test...
      myfn();  // this fn is already execute
      Copy the code

The above code implements the higher-order function once through closures to cache the results of function execution.

To sum up, closures in JS can bring us a lot of convenience. However, when using the cache feature, it is necessary to pay attention to the local variables in the cache that reside in the memory, causing memory leaks. Therefore, unnecessary local variables can be manually deleted in the process of use.

References developer.mozilla.org/zh-CN/docs/…


  • This is element3, the open source project of our Flower Mountain front end team
  • A front-end component library that supports VUE3