The sea is wide by diving, the sky is high as birds fly. Hey how are you! I’m Molly

Closures have been a platitude, and different people have different understandings of closures. Today I’m going to talk about closures, and we’re going to discuss the topic of “closures”, hoping to rub out some different sparks.

Before we understand closures, we need to understand context and scope

context

When a browser engine parses JS code, it generally goes through two phases. Parsing phase and execution phase

Analysis stage: A piece of code to put it bluntly, it’s just a regular code text so js engine will get code parsing code in advance, the initialization process variables, parameters, function, expression, operator and so on to extract coexist, and the default assignment for undefined variable, function default to function block, determine the context and a series of preparations

Execution stage: execute the code line by line from top to bottom. When encountering the corresponding variable or function, go to the warehouse for matching execution

console.log(str);
console.log(fun);
var str = "molly";
let str1;
console.log(str1);
function fun(a, b) {
    return a + b;
}
Copy the code

Definition: Context can be divided into the global context and local context, context determines the variable or function they can access what data, as well as their behavior (good) were fixed initialization phase, each a context has a variable object (environment), all of the variables and functions defined in this context will be stored in the variable object, We can’t access this variable object directly from the code, but we can see it through the break point.

The global context is destroyed before the program exits (such as closing the web page or exiting the browser), and the local context is destroyed after its code has finished executing

So what does this variable object look like? Take your time. Let’s move on

Context execution stack

Definition: Each function call has its own context. When the function is executed, the context of the function will be pushed onto a context execution stack. After the function is executed, the context execution stack will pop up the context of the function, returning control to the previous execution context.

// A simple example, breakpoints debug call stack and context variable objects
let a_name = Force "cat";
var a_sex = "Male";
var a = "111";
function a_molly(age) {
    let a_like = "Love to learn";
    var a_like2 = "Love sports";
    a_say(a_like);
    var a = "222";
    console.log(a);
    let test = "Coming?";
}
function a_say(a_like) {
    let code = "Knock code";
    console.log(a_like);
}
a_molly();
Copy the code

With the example code above, we set a breakpoint on the console to watch the call Stack execute

Notice the call Stack on the left and the scope on the right and the breakpoint location

By observing the breakpoint debugging results, we can draw the following conclusions:

  • When the script is initialized, a global context is pushed to the bottom of all context execution stacks, i.eGlobalattribute
  • Each time a function is executed, a “function context” is appended to the execution stack.
  • When the function completes execution, the corresponding “function context” is cleared
  • Within each context, accessible data is identified

Scope and scope chain

When the code in the context executes, it creates a chain of scopes for the variable object. This chain of scopes determines the order in which the code at each level of context accesses variables and functions. The scope is the containment relation, and the global contains the local.

Conclusion:

Context relates variable objects to determine which data functions can access, while scope determines the rules for data access.

Simply put, the access rules for scopes can be summed up as follows: look-in access, inside access to the outside and outside access to the inside, which can be called the scope chain

Function parameters are considered variables in the current context and therefore follow the same access rules as other variables below.

closure

Now that we have a brief overview of “context” and “scope,” it’s nice to talk about closures

Definition of closure

Little Red Book: Closures are functions that reference variables in the scope of another function

MDN: A combination of a function bound (or surrounded by) references to its surrounding state (lexica 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.

A closure is a function that can read variables inside other functions. Local variables can be read only by subfunctions inside a function, so closures can be understood simply as “functions defined inside a function”.

To summarize: the execution of a function can trigger the definition of another function (function declaration, function expression) and can reference variables in the scope of another function. So this function is a closure

Why are there closures?

To sum up, we can know that the local scope can access the global scope, but the global can not access the local, two irrelevant parts can not access each other, so, as long as the mind does not slide, the method is always more than difficult, to solve this kind of problem, we need to adapt, the conclusion is: “closure”.

Closures are like Bridges that connect disparate scopes to each other.

Closures take advantage of variable environments and scope-chain access rules

The purpose of closures

Closures have two main uses

  1. You can read variables inside the function body
  2. Keep the closure’s variables in memory at all times

Closure form:

Think of the function as a first-class citizen, as an ordinary variable

1: Returns a function

function fun(){
    var aaa = 111
    return function(b){
        returnAaa + B}} Fun ()() Classic scenario: anti-shake throttlingCopy the code

2: Returns a function variable

function fun(a){
    let fn =  function(b){
        return a+b
    }
    return fn;
}
fun()()
Copy the code

3: as a global closure function

var call;
function fun(a){
    call =  function(b){
        return a+b
    }
}
fun()
call()
Copy the code

4: Passed as a function parameter

function fun1(fn){
    fn() // The fn function is the closure
}
function fun2(){
    let str = 'molly'
    function fun3(){
        console.log(str)
    }
    fun1(fun3)
}
fun2()
Copy the code

5: callback function


function ajax(data){
    console.log(data)
}
function sync(){
    const obj = {name:'molly'.a:a}
    ajax(obj)
}
Copy the code

6: IIFE executes the function immediately

; ! (function(){... }); Classic scene:for(var i = 1; i <=5; i++){ (function(j){
    setTimeout(function timer(){
      console.log(j)
    }, 0(I)} jquery custom wrapped plug-ins also start with immediate function executionCopy the code

Advantages of closures:

  1. You can access two unrelated scope variables
  2. As a sandbox, store variables
  3. Code encapsulation, tool functions
  4. Function as value, takes in and returns

Disadvantages of closures:

  1. Memory leaks

How do you avoid memory leaks?

  1. Point the function pointer tonull, into the scope of garbage collection
  2. The closure completes execution
function fun(a){
    return function(b){
        return a+b
    }
}
let a = fun()
a=nullOr the closure also completes a()Copy the code

Js garbage collection mechanism can be roughly divided into two types: “tag cleanup” and “count references”. When a variable inside a closure is used in another function, it is not identified as garbage, but is resident in memory and is not cleaned up. This results in extra memory consumption

Ask questions?

Do you know of any scenarios or code that makes clever use of closures? Welcome to discuss in the comments section!

Thank you

Welcome to pay attention to my personal public number front end of the cat every day to push you fresh quality good article. Reply “benefits” and you will get my carefully prepared front-end knowledge gift package. May you go all the way with light in your eyes!

Interested partners can also add my wechat: Molly or front-end communication group and many excellent front-end siege lions to exchange technology, play together!