Closures are a common feature of many languages. Functional Programming from Abstract Algebra — Part 1: Definitions of Closures in Java/PHP/JS

The characteristics of closures

Closures have three features:

  • Function nested function

  • Functions can reference external parameters and variables inside

  • Parameters and variables are not collected by the garbage collection mechanism

In JS, closures refer to several other features of JS: scope chains, garbage (memory) collection mechanisms, function nesting, and so on.

Closures are a feature of the Javascript language (functional programming features), and many advanced applications rely on closures. But JavaScript is a bit of a challenge, because JavaScript is born prematurely and is not as distinct as strongly typed languages. To quote the passage from ECMAScript: The Coronation of JavaScript, the King of Web scripting:

Javascript actually ** (simplified) functional programming + (simplified) object-oriented programming **, which was decided by Brendan Eich (functional programming) and Netscape (object-oriented programming). It’s a freak of C and Self one-night stands. ‘What’s good about it isn’t original. What’s original about it isn’t good. ‘

In general, Brendan Eich’s design approach goes like this:

  1. Learn from the basic syntax of C language;

  2. Using the Java language for data types and memory management;

  3. Using Scheme language to elevate functions to the status of “first class”;

  4. Reference Self language, using prototype – based inheritance mechanism.

…………………

Reason 1: Javascript is a functional programming language, but it also has this pointer, which means it is also an object-oriented language. To be more specific, javascript functions are higher-order functions, and higher-order functions in programming languages can be passed as objects. Javascript functions can also be used as constructors, which can create instantiated objects. As a result, the pointer to this can change during method execution, which is difficult to control. 支那

Reason two: The global scope in javascript has a big effect on this pointer. As we saw in the Java example above, this pointer only works when the new operator is used, but this in javascript also works when the new operator is not used. This usually refers to the global object Window.

Reason 3: The call and apply operators in javascript can change the pointer to this at will. This may seem flexible, but this unintuitive approach destroys our understanding of the purpose of the pointer and makes it difficult to understand what this really points to when writing code

Interprets JS closure functions

Before we understand closures. JavaScript garbage collection: Analyzing and Troubleshooting MEMORY Leaks

Javascript garbage collection

  • Reference counting: Tracks the number of references to a value. When a variable is declared and a reference type is assigned to the variable, the number of references to the value increases by 1. When the variable points to another value, the number of references to the value decreases by 1. The value is reclaimed when the number of references is zero. This approach causes memory leaks because it does not solve the problem of circular references: var a={}; var b={}; a.prop = b; b.prop = a;

  • Mark and sweep: Most browsers recycling in this way, when variables into the execution environment () function declared in variable, garbage collector will mark it as “into the environment”, when the variable from the environment (function) to be marked as “out of the environment”, after leaving the environment and the variables are variables need to be deleted. The notation varies, from the inversion of a particular bit to the maintenance of a list.

    The garbage collector marks all variables in memory and then removes the marks of variables in the environment and those referenced by variables in the environment. Variables tagged after this point are the ones that need to be reclaimed because they are no longer accessible to variables in the environment.

All we need to remember is:

  • In javascript, if an object is no longer referenced, it is reclaimed by GC;

  • If two objects refer to each other and are no longer referenced by a third party, the two objects referred to each other are also reclaimed.

JavaScript scope chain

Simply put, a scope chain is an index created at the time a function is defined to find the value of the variable being used, and its internal rules are:

  • Put the function’s own local variables first,

  • Put variables in its parent function next

  • Put the variables in the higher-order function further back

  • … And so on up to the global object

When a function needs to look up the value of a variable, the JS interpreter goes to the scope chain to look it up. If the corresponding variable is not found, go to the next level of the chain. Once the variable is found, the chain does not continue. If the desired variable is not found, the interpreter returns undefined.

In general, at the beginning of the execution of a function, the variables defined in the function are stored in memory for later statements. By the time the function returns from execution, these variables are considered useless. The corresponding memory space is reclaimed. The next time this function is executed, all variables are returned to their original state and reassigned.

However, if the function is nested inside another function, this function may be called from outside. And the inner function uses some variables of the outer function. The problem with this reclaiming mechanism is that if the inner function is called directly after the return of the outer function, the inner function cannot read the values of the variables in the outer function that it needs. So when the JavaScript interpreter encounters a function definition, it automatically saves the function along with any variables it might use (including local variables and variables (free variables) of parent and ancestor functions) **. Is constructing a closure, these variables will not be recycled by memory collector, only when the internal function cannot be called (such as deleted, or not the pointer), will destroy the closure, without any a closure reference variables can be reclaimed by next time memory recovery starts * *.

That is, with closures, nested function structures can work, which is what we expect.

In daily life, when we go to the Communist Party of China and look for A to handle affairs, you have to look for B to stamp your stamp on the door. B said that you have to look for C to stamp your stamp on the door. C said that this thing is not our scope of competence… Kick the ball, that’s a non-closure. The closure is to go to the end, you go to Department A, and the person who works with Department A goes to the end, and he or she coordinates between Department B and Department C.

In engineering, closures are project managers who are responsible for scheduling the resources needed for a project. If the boss or client has any problem, go directly to the project manager instead of going to other people.

Definitions of closures and an overview of their strengths and weaknesses

A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within a function and access local variables of that function through another function.

Disadvantages of closures

After a function is executed, the local active object is destroyed and only the global scope is kept in memory. But closures are different!

The downside of closures is that they live in memory, which increases memory usage and can cause memory leaks if used improperly.

Benefits of using closures

So what are the benefits of using closures? The benefits of using closures are:

  • You want a variable to stay in memory for a long time

  • Avoid contamination of global variables

  • The existence of private members (design private methods and variables).

Closure of a nested function

function closure () { var a = 1; return function () { console.log(a++); }; } var fun = closure(); fun(); // a++, and a is still in ~ fun(); // 2 fun = null; //a is collected!!Copy the code

Closures keep variables in memory at all times, which can increase memory consumption if improperly used.

The code demonstrates the JS closure

talk is cheap ,show me code

The sum of global variables

var a = 1; function abc(){ a++; console.log(a); } abc(); // 2 abc(); / / 3Copy the code

2. Local variables

function abc(){ var a = 1; a++; console.log(a); } abc(); // 2 abc(); / / 2Copy the code

So how do you make a local variable and add up?

Third, the accumulation of local variables

function outer () { var x = 10; Return function () {x++; alert(x); }; } // The external function is assigned to the variable y; var y = outer(); Outer ()(); outer()(); y(); // call y the second time, the result is 12, implement the accumulation of y();Copy the code

Function declarations and function expressions

In js we can declare a function with the keyword function:

function abc () {
    console.log(123);
}
abc();
Copy the code

We can also turn this declaration into an expression with a “()” :

// Then call the preceding expression directly through (), so the function does not need to write the name; (function () { console.log(123); }) ();Copy the code

Four, modular code, reduce the pollution of global variables

Var ABC = (function(){// ABC = 1; return function(){ a++; console.log(a); }}) (); abc(); / / 2; Call ABC (); call ABC (); / / 3Copy the code

5. The existence of private members

var aaa = (function(){ var a = 1; function bbb(){ a++; console.log(a); } function ccc(){ a++; alert(a); } return {b: BBB, c: CCC} //json structure})(); aaa.b(); //2 aaa.c(); / / 3Copy the code

Use anonymous functions for accumulation

function box(){ var age = 100; Return function(){// anonymous function age++; return age; }; } var b = box(); console.log(b()); console.log(b()); / / alert (box () ()); console.log(b()); console.log(b); b = null; // Dereference and wait for garbage collectionCopy the code

Find the index of the corresponding element directly in the loop

window.onload = function () { var aLi = document.getElementsByTagName('li') for(let i =0 ; i<aLi.length; i++){ (function () { //TODO })(i) } };Copy the code

9. Memory leak problem

Because IE uses different garbage collection methods for JS objects and DOM objects, closures can cause memory leaks in IE, that is, the inability to destroy elements residing in memory

function closure(){ var oDiv = document.getElementById('oDiv'); Odiv.onclick = function () {console.log(' odiv.innerhtml '); // oDiv causes memory leak}; } closure(); Function closure(){var oDiv = document.getelementById ('oDiv'); function closure(){var oDiv = document.getelementById ('oDiv'); var test = oDiv.innerHTML; oDiv.onclick = function () { alert(test); }; oDiv = null; }Copy the code

(4) The function of a computer is a function of a computer

The reprint the home station article from lambda calculus to functional programming about closure (2) : thoroughly understand JavaScript closure rules, please indicate the source: www.zhoulujun.cn/html/webfro…