Closure

  1. Closure

    When a function is defined, it holds a reference to the external environment in which it exists. This means that a function can access variables in the scope in which it is defined, and this scope chain is determined when the function is defined, not when the function is called.

    Closure is when an internal function refers to or uses the local variables of its external function, the whole formed by the internal function (and the local variables of the included external function) is called a closure.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function outer() {
    let localVariable = "I'm a local variable";

    function inner() {
    console.log(localVariable);
    }

    return inner;
    }

    const myClosure = outer();
    myClosure(); // Output: "I'm a local variable"

    • outer is an external function that defines a local variable localVariable and an inner function inner.

    • The inner function accesses the localVariable in its outer scope.

    • When we call the outer function, it returns the inner function and assigns it to myClosure.

    • Even though the execution context of the outer function has ended, it still has access to localVariable when we call myClosure. This is because of the role of closures.


  2. Common application scenarios of Closure

    1. Private variables: Closures can simulate the concept of private variables, because the outer scope cannot directly access the variables in the inner function.

    2. Event handlers and callbacks: When using event handlers or callbacks, you may want certain information to be remembered by the callback function. Closures are one way to achieve this.

    3. Dynamically generated functions: Functions with specific behaviors can be dynamically created and returned.


  3. Disadvantages of Closure: Memory

    Since closures refer to variables and functions outside of them, as long as the closure exists, these variables will not be recycled by the garbage collection mechanism, which may lead to memory leaks. You need to make sure to dereference these closures when they are no longer needed.

    Overuse of closures can cause performance issues because of the overhead of creating the closure and maintaining a reference to the outer scope. Even though closures are optimized in most modern browsers, it’s still something to be aware of in performance-critical scenarios.


  4. Method to create Closure

    In addition to functions, closures may be created by constructors, setTimeout, event handlers, etc.


  5. Loops and Closures

    When using closures within loops, you may encounter some unexpected behavior. For example:

    1
    2
    3
    4
    5
    for (var i = 0; i < 3; i++) {
    setTimeout(function() {
    console.log(i);
    }, 1000);
    }

    You might expect it to print 0, 1, and 2, but instead it prints 3, 3, and 3. This is because closures hold references to variables, not values. When the setTimeout callback is executed, the value of i is already 3. To solve this problem, you can use more closures or use the let keyword instead of var.


Share