What is a closure

A closure is a combination of functions bundled together (closed) and references to their surrounding state (lexical environment). —mdn

Functions that refer to variables in the scope of another function, usually implemented in nested functions. – the little red book

Closures occur when a function can remember and access its lexical scope, even if the function is executed outside the current lexical scope. — Js you don’t know

The nature of closure formation

The essence of JavaScript closures comes from two things, lexical scopes and functions passed as values.

Lexical scope

Lexical scope, also known as static scope, is defined from the beginning.

The engine represents a function through data structures and algorithms that allow access to peripheral variables that are registered in the corresponding data structure in accordance with the rules of lexical scope during code interpretation execution.

Value passed

Arguments to all functions in ECMAScript are passed by value. – the little red book

A function is returned as a value, also is equivalent to return to a channel, the channel access to this function the lexical scope of variables, namely the function required by the data structure is preserved, the values in the data structure in execution is created when the outer function, when the outer function has been completed for destruction, but due to the internal function as a value back out, These are worth preserving. And you can’t access it directly, you have to go through the returned function. This is also called private sex.

Classic closure

The 30 second example

const initCounter = (start = 0) = > {
  let value = start;
  return {
    get: () = > value,
    increment: () = > ++value,
    decrement: () = > --value,
    reset: () = > value = start
  };
}

const counter = initCounter(5);
counter.get(); / / 5
counter.increment(); / / 6
counter.increment(); / / 7
counter.decrement(); / / 6
counter.reset(); / / 5
Copy the code

All properties that return objects use closures to manipulate the value variable of initCounter in some way.

The initCounter function returns the enclosing block scope as a closure.

While value is a free variable that can be used inside a closure, the obvious benefit of this approach is that if you want to define multiple counters, initCounter, you don’t need value to create multiple instances everywhere, but they are safely encapsulated by the returned object, using a closure.

You don’t know js

var fn;
function foo() {
var a = 2;
function baz() {
console.log( a );
}
fn = baz; // Assign baz to the global variable
}
function bar() {
fn(); // This is a closure!
}
foo();
bar(); / / 2
Copy the code

MDN example

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();
Copy the code

Closure usage scenarios

Closures are everywhere, a successful callback to an Ajax request, an event-bound callback method, a delayed callback to a setTimeout, or a function that returns another anonymous function within itself. In short, no matter how you pass a value of a function type, the closure is always present when the function is called elsewhere.

A closure is useful for reading variables inside an outer function, and for keeping those variables in memory at all times. A closure is useful for keeping the environment in which it was created. In the example below, closures cause internal variables to remember the result of the last call.

function createIncrementor(start) {
  return function () {
    return start++;
  };
}

var inc = createIncrementor(5);

inc() / / 5
inc() / / 6
inc() / / 7
Copy the code

Closures are also useful for encapsulating the private properties and methods of an object.

function Person(name) {
  var _age;
  function setAge(n) {
    _age = n;
  }
  function getAge() {
    return _age;
  }

  return {
    name: name,
    getAge: getAge,
    setAge: setAge
  };
}

var p1 = Person('Joe');
p1.setAge(25);
p1.getAge() / / 25
Copy the code

Note that each time the outer function is run, a new closure is generated, which in turn preserves the inner variables of the outer function, so memory consumption is high. Therefore, you should not abuse closures, which can cause performance problems for your web pages.

conclusion

Explanation in one sentence: when a function is created and passed or returned from another function, it carries a backpack. The knapsack contains all variables that are in scope when the function is declared.

Ruan Yifeng explains

A closure is a bridge that connects the inside and outside of a function.

Closure formation is very simple, after the execution of the process, return the function, or the function is preserved, that is, to form a closure.