1. SetTimeout for closure scenarios

The first function passed by a native setTimeout cannot take arguments, and can be passed by closures

    setTimeout(function(param){alert(param)},1000function func(param){
        return function(){
            alert(param)
        }
    }
    var f1 = func(1);
    setThe Timeout (f1, 1000);Copy the code

2. Callbacks for closure application scenarios

We define the behavior and then associate it with a user event (click or button). Our code is usually bound to the event as a callback (the function that is called when the event fires)

<body> <p> hahaha hahaha </p> <h1> HHHHHHHHH </h1> <h2> QQQQQQQQQ </h2> <a href="#" id="size-12">12</a>
    <a href="#" id="size-14">14</a>
    <a href="#" id="size-16">16</a>

<script>
    function changeSize(size){
        return function(){
            document.body.style.fontSize = size + 'px';
        };
    }

    var size12 = changeSize(12);
    var size14 = changeSize(14);
    var size16 = changeSize(16);

    document.getElementById('size-12').onclick = size12;
    document.getElementById('size-14').onclick = size14;
    document.getElementById('size-16').onclick = size16;
</script>
</body>
Copy the code

3. Encapsulating variables for closure application scenarios

Use closures to define public functions that can access private functions and private variables

    var counter = (function(){ var privateCounter = 0; // Private variablesfunction change(val){
            privateCounter += val;
        }
        return {
            increment:function(){// Three closures share a lexical environment change(1); }, decrement:function(){
                change(-1);
            },
            value:function() {returnprivateCounter; }}; }) (); console.log(counter.value()); //0 counter.increment(); counter.increment(); / / 2Copy the code
  1. The shared environment is created in the body of an anonymous function and executed immediately.
  2. The environment has one local variable and one local function, accessed through three public functions of the object returned by the anonymous function.
Another example: creating a counter in JavaScript:
'use strict';
function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function () {
            x += 1;
            returnx; }}}Copy the code

Running results:

var c1 = create_counter(); c1.inc(); // 1 c1.inc(); // 2 c1.inc(); // 3 var c2 = create_counter(10); c2.inc(); // 11 c2.inc(); // 12 c2.inc(); / / 13Copy the code

In the returned object, a closure is implemented that carries the local variable X, which is not accessible from external code at all. In other words, closures are functions that carry state, and their state can be completely hidden from the outside world.

4. Closures are used for loop binding click events to nodes

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;
}

var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
Copy the code

In the above example, each time a new function is created through the loop, it is returned that all three functions created are added to an Array.

You might think that calling f1(), f2(), and f3() would result in 1, 4, 9, but the actual result is:

f1(); // 16 f2(); // 16 f3(); / / 16Copy the code

They’re all 16’s! The reason is that the returned function refers to variable I, but it is not executed immediately. By the time all three functions return, the variable I referenced by them has changed to 4, so the final result is 16.

One thing to keep in mind when returning closures is that the return function should not reference any loop variables, or variables that will change later.

What if you must reference a loop variable? The method is to create another function that binds the current value of the loop variable with its arguments. The values that are bound to the function remain unchanged, regardless of subsequent changes to the loop variable:

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));
    }
    returnarr; } var results = count(); var f1 = results[0]; var f2 = results[1]; var f3 = results[2]; f1(); // 1 f2(); // 4 f3(); / / 9Copy the code

Note the syntax “create an anonymous function and execute it immediately” :

(function (x) {
    returnx * x; }) (3); / / 9Copy the code

5. ES6 inadvertent closure application

Sometimes closures pop up when you don’t expect them to, and you may have seen an example of what we call a local application, as shown in the code below.

let c = 4
const addX = x => n => n + x
const addThree = addX(3)
let d = addThree(c)
console.log('example partial application', d)
Copy the code

If the arrow function is not used, the equivalent code is as follows:

let c = 4
function addX(x) {
  return function(n) {
     return n + x
  }
}
const addThree = addX(3)
let d = addThree(c)
console.log('example partial application', d)
Copy the code

We declare a generic addition function, addX, that takes one argument (x) and returns another function.

The returned function also takes an argument and adds it to the variable x.

The variable X is part of a closure, and when the variable addThree is declared in a local context, it is assigned a function definition and a closure that contains the variable X.

So, when addThree is called and executed, it can access variables X and n from the closure (passed in as arguments) and return the sum.

In this example, the console will print the number 7.

Reference article links:

  1. Blog.csdn.net/qq_21132509…
  2. www.liaoxuefeng.com/wiki/102291…