search

Home  >  Q&A  >  body text

How do JavaScript closures work?

<p>How to explain closures to someone who understands the concept of JavaScript closures (such as functions, variables, etc.), but does not understand closures themselves? </p> <p>I've looked at the Scheme examples given on Wikipedia, but unfortunately they didn't help. </p>
P粉494151941P粉494151941505 days ago464

reply all(2)I'll reply

  • P粉734486718

    P粉7344867182023-08-23 09:30:55

    In JavaScript, each function maintains a link to its external lexical environment. The lexical environment is a map of all names (such as variables, parameters) and their values ​​in a scope.

    So, whenever you see the function keyword, code inside that function can access variables declared outside the function.

    function foo(x) {
      var tmp = 3;
    
      function bar(y) {
        console.log(x + y + (++tmp)); // 将输出 16
      }
    
      bar(10);
    }
    
    foo(2);

    This will output 16 because the function bar closes the parameter x and the variable tmp, which both exist in the outer function# in the lexical environment of ##foo.

    Function

    bar, together with its link to the lexical environment of function foo, forms a closure.

    Functions are not required to

    return to create a closure. By declaration alone, each function encloses its enclosing lexical environment, forming a closure.

    function foo(x) {
      var tmp = 3;
    
      return function (y) {
        console.log(x + y + (++tmp)); // 也将输出 16
      }
    }
    
    var bar = foo(2);
    bar(10); // 16
    bar(10); // 17

    The above function will also output 16 because the code in

    bar can still reference the parameter x and variable tmp, even though they are no longer directly in scope.

    However, since

    tmp still exists within bar's closure, it can be incremented. It will be incremented each time bar is called.

    The simplest example of a closure is:

    var a = 10;
    
    function test() {
      console.log(a); // 将输出 10
      console.log(b); // 将输出 6
    }
    var b = 6;
    test();

    When a JavaScript function is called, a new execution context

    ec is created. In addition to the function parameters and the target object, this execution context also receives a link to the lexical environment of the calling execution context, which means variables declared in the external lexical environment (in the example above, that is, a and b) can be accessed from ec.

    Every function creates a closure because every function has a link to its external lexical environment.

    Please note that what is visible in the closure is the variable itself, not the copy.

    reply
    0
  • P粉904405941

    P粉9044059412023-08-23 00:50:56

    A closure is a pair of:

    1. A function and
    2. Reference to the external scope (lexical environment) of the function

    The lexical environment is part of every execution context (stack frame) and is the mapping between identifiers (i.e. local variable names) and values.

    Every function in JavaScript maintains a reference to its external lexical environment. This reference is used to configure the execution context created when the function is called. This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.

    If a function is called by another function, a series of references to the external lexical environment will be created. This chain is called the scope chain.

    In the following code, inner forms a closure with the lexical environment of the execution context created when foo is called, and the closure contains the variable secret:

    function foo() {
      const secret = Math.trunc(Math.random() * 100)
      return function inner() {
        console.log(`The secret number is ${secret}.`)
      }
    }
    const f = foo() // 无法直接从外部访问`secret`
    f() // 检索`secret`的唯一方法是调用`f`

    reply
    0
  • Cancelreply