This article has participated in the comment drawing peripheral gift activity, digging gold badge *2, comments related content can participate in the lucky draw to see details

preface

This article is very basic, suitable for students who have not learned about closures. I often use JS to write business logic, but I have not deliberately used closures. If you are similar to me, then follow this article, you will definitely learn something.

Enter today’s theme closure.

closure

What is a closure

Closures are the difficulty and hallmark of JavaScript. Is one of the so-called three mountains of JS interviewing (prototype and prototype chain, scope and closure, asynchronous and single-threaded).

A lot of advanced applications need to rely on closures to experiment, including we go to see a lot of JS libraries and framework source code, not without closure shadow.

define

Closures are functions that can read variables inside other functions.

Why do we use closures to read variables inside other functions?

Because what’s special about JavaScript is that you can read global variables directly from inside a function, but you can’t read local variables directly from outside a function. Local variables can only be read by children inside a function, as shown in the following example.

// This section is just to demonstrate that global and local variables are independent of closures
  // Global variables can be accessed anywhere
  let s = 100;
  function foo() {
    // Local variables are created at run time and destroyed after execution
    let a = 10;
    function boo() {
      console.log('🚀 🚀 ~ boo:', a); / / 🚀 🚀 ~ boo: 10
    }
    boo()
  }
  foo()
  console.log(' '🚀 🚀 ~ s., s); / / 🚀 🚀 ~ s: 100
  console.log(A: '🚀 🚀 ~', a); // Uncaught ReferenceError: a is not defined
Copy the code

So closures can simply be understood as functions defined inside a function. Closures are essentially Bridges that connect the inside and outside of a function.

How to read a local variable inside a function from the outside

Let’s start with a question. How do I read local variables inside a function from outside? However, local variables inside a function cannot be read directly from outside the function.

Yeah, we can’t read it directly, but we can work around it.

The first is to return.


  function foo() {
    let a = 88;
    return a;
  }
  console.log('a' 🚀 🚀 ~., foo()); // 🚀🚀~ : a 88

Copy the code

The second type is the subfunction mentioned above.

  function foo() {
    let a = 99;
    function boo() {
      console.log(A: '🚀 🚀 ~', a);
    }
    boo();
  }
  foo();/ / 🚀 🚀 ~ a: 99
Copy the code

I’m going to leave you with a question.

  • According to the definition of a closure, a closure is a function that reads variables inside other functions. If not, they both get the value of the local variable and it’s easier, so why use closures?

Why do YOU need closures

Local variables are created during the execution of a function, and destroyed after the function is executed. There is no way to preserve state and share it for long.

Global variables can pollute variables, making code difficult to read and maintain.

We wanted an operation that could hold variables for a long time without causing global contamination, and closures were born.

The way to write closure

  function f1() {
    let a = 10;
    function f2() {
      a++;
      console.log(A: '🚀 🚀 ~', a);
    }
    return f2;
  }
  let fn = f1(); // the result of f1 execution is closure
  fn()
Copy the code

Think of problem solutions

Now, why do we need closures when subfunctions and direct returns can get the value of a local variable?

  / / closures
  function f1() {
    let a = 10;
    function f2() {
      a++;
      console.log(A: '🚀 🚀 ~', a);
    }
    return f2;
  }
  let fn = f1(); 
  fn();
    
  / / return directly
  function f3() {
    var a = 10;
    a++;
    return a
  }
 console.log(A: '🚀 🚀 ~',  f3());
  
  / / function
  function f4() {
    let a = 10;
    function f5() {
      a++
      console.log(A: '🚀 🚀 ~', a);
    }
    f5();
  }
  f4();
Copy the code

You can see that the console output is the same.

So how many times do we call it?

  / / closures
  function f1() {
    let a = 10;
    function f2() {
      a++;
      console.log('🚀🚀~ closure ~ a:', a);
    }
    return f2;
  }
  let fn = f1(); // the result of f1 execution is closure
  fn();
  fn();
  fn();
  fn();

  //return
  function f3() {
    let a = 10;
    a++;
    console.log('🚀 🚀 ~ return a:', a);
  }
  f3();
  f3();
  f3();
  f3();


  / / function
  function f4() {
    let a = 10;
    function f5() {
      a++
      console.log('🚀🚀~ subfunction a:', a);
    }
    f5();
  }
  f4();
  f4();
  f4();
  f4();
Copy the code

Did you notice anything? We’re using closures, and every time we call it, variable A is going to be +1, and we’re just going to return and subfunctions, and every time we call it, variable A is going to be 11.

The questions I left before I got here are already answered. A closure is a function that can read the internal variables of other functions. However, a function that can read the internal variables of other functions is not necessarily a closure. Why is a closure needed?

Disadvantages of closures

The advantages have already been discussed, so what are the disadvantages of closures? Normally, a function’s live object is destroyed along with the context in which it is executed, but because a closure refers to an external function’s live object, it cannot be destroyed, which means that closures consume more memory than normal functions.

Case – Cache

  const cacheMemory = (() = > {
    let cache = {}
    return {
      set: (id) = > {
        if (id in cache) {
          return 'And the result is${cache[id]}`
        }
        const result = asyncFn(id);// Emulate asynchronous results
        cache[id] = result
        return 'And the result is${cache[id]}`}}}) ()Copy the code

Case – Simulation stack

  const Stack = (() = > {
    let arr = [];
    return {
      push: (value) = > {
        arr.push(value)
      },
      pop: (value) = > arr.pop(value),
      size: () = > arr.length,
    }
  })()

  Stack.push("a")
  Stack.push("b")
  console.log('🚀 🚀 ~ Stack. Size:', Stack.size()); / / 2
  console.log('🚀 🚀 ~ Stack. Pop (" b ") :', Stack.pop("b")); // b
  console.log('🚀 🚀 ~ Stack. Size:', Stack.size()); / / 1
Copy the code

Draw a statement

By September 10th, if more than 10 people (not including the author) interact in the comments section, the author can draw 2 nuggets badges in his own name (nuggets official bear).

This event is supported by Nuggets officials for details. The author is the third one on the list.

Note:

  • Comments must be relevant to the article.
  • The prizes will eventually be distributed to the review users, the review users are gold digging, there is no fixed. After winning the prize, I will leave wechat in your comments. Please take the initiative to add and tell me the delivery address.
  • If the user does not meet the comment requirements, use the simplestrandomThe function sweepstakes.

reference

Explain the front end