JavaScript you don't know scope closure

Source: Internet
Author: User
Tags closure

One, what is closures
functionfoo () {varA = 2; //the lexical scope of the function bar () can access the internal scope of the function foo (). Pass the bar () function as a value.      //Bar () declares within Foo () that it has a closure that covers the internal scope of Foo (), allowing the scope to survive until bar () is referenced at any later time. Bar () itself uses the internal scope of Foo (), so Foo will not be destroyed after execution.     functionBar () {Console.log (a); }    returnBar;}//Bar () can run normally and is executed outside of its lexical scope. varBaz =foo ();//after Foo () executes, its return value bar () function is assigned to the variable Baz and called Baz (), which is actually called the internal function bar (). Baz ();

Bar () still holds a reference to the scope, which is called a closure .

Regardless of whether an intrinsic function is passed outside the lexical scope by any means, it will have a reference to the original definition scope, and no matter where the function is executed, the closure will be generated.

function foo () {    var a = 2;     function Baz () {        //  2    }    Bar (baz);} function Bar (FN) {    //  closures }

var fn; function foo () {    var a = 2;     function Baz () {        console.log (a);    }     = baz ();} function Bar () {    //  closed package }foo (); bar ();

The internal function timer is passed to the Settimeout,timer that covers the wait scope, so a reference to the message is retained. After wait executes 1000 milliseconds, its internal scope does not disappear, and the timer function retains the wait-scoped closure.

function Wait (message) {    for (var i = 0; I <= 5; i++) {    function  timer () {        console.log (i);    }, I*1000);}    }

If you use functions that access their respective lexical scopes as first-level value types and pass around, you can see how closures are applied to these functions. In timers, event listeners, Ajax requests, cross-window communication, WEB workers, or any other asynchronous (synchronous)

In a task, a closure is used whenever a callback function is used.

function Setup (name, selector) {    function  activator () {        "activating:" + name);       });    "Closure bot 1", "#bot_1""Closure bot 2", "#bot_2");

The function iife is not executed outside of its lexical scope, but at the scope where it is defined. A is found by ordinary lexical scopes rather than closures. Although Ieff itself is quite a good example of observing closures, it does create closures,

It is also the most commonly used tool to create closures that can be closed.

var a = 2;(function  iife () {    console.log (a);} ());

Loops and closures

for (var i = 0; I <= 5; i++) {
SetTimeout (function () {
Console.log (i);
}, i*1000);
}

Output 5 x 6 per second

the callback for the deferred function executes only after the loop has finished . When the timer is running, even if settimeout (..., 0) is executed in each iteration, all the callback functions are still executed after the loop is completed.

According to the scope principle, although the five functions of a loop are defined separately in each iteration, they are all in the global scope and actually have only one I.

More closure scopes are required, especially in the case of loops where the closure scope is required for each iteration.

This example cannot be achieved
 for (var i = 0; I <= 5; i++) {     (function() {          function()               { Console.log (i);          }, I*1000);     } ())}/ / Each delay function is closed in the scope created by the Iife in each iteration /// But here is an empty scope

It needs to have its own variables that are used to store I in each iteration.

 for (var i = 0; I <= 5; i++) {    (function() {        var j = i;         function () {            console.log (j);        }, J*1000);    } ())}

Slightly improved

 for (var i = 0; I <= 5; i++) {    (function(j) {        function()            { Console.log (j);        }, J*1000);    } (i))}

Using Iife within an iteration will generate a new scope for each iteration, so that the callback for the deferred function can enclose the new scope within each iteration, and each iteration will contain I a variable with the correct value.

Using block scopes
 for (var i = 0; I <= 5; i++) {    = i;  // block scope    for closures function Timer () {        console.log (j);    }, J*1000);}

The let declaration for a For loop has a special behavior where the variable is declared more than once during the loop, and each iteration is audible. Each subsequent iteration initializes the variable with the value at the end of the previous iteration.

 for (Let i = 0; I <= 5; i++) {    function  timer () {        console.log (i);    }, I*100 0);}

Module
functionCoolmodule () {varsomething = "cool"; varanother = [1, 2, 3]; functiondosomething () {console.log (something); }    functionDoanother () {Console.log (Another.join (" ! " ) ); }    return{dosomething:dosomething, doanother:doanother};}varFoo =coolmodule (); foo.dosomething ();//CoolFoo.doanother ();//1! 2! 3

This model is becoming a module, the most common way of implementing modules is exposed as modules, here is its variant.

First, Coolmodule () is just a function that must be called to create an instance of a module. If you do not execute an external function, neither the inner scope nor the closure can be created.

Second, Coolmodule () returns an object literal syntax {key:value, ...} To represent the object. This object contains a reference to an intrinsic function rather than an intrinsic variable. Outside to keep internal variables is hidden and private state. You can consider the return value of this object type as essentially a public APIfor the module.

The return value of this object type is eventually assigned to the external variable foo, which can then be used to access the API's property methods.

    • It is necessary to return the actual object from the module, and an intrinsic function, such as jquery, can be returned.

Module mode requires two necessary conditions.

    1. There must be an external enclosing function that must be called at least once (each call creates a new instance of the module).
    2. The enclosing function must return at least one intrinsic function in order for the intrinsic function to form a closure in the private scope and to access or modify the private state.

When you need only one instance, you can implement a singleton pattern:

varFoo = (functionCoolmodule () {varsomething = "cool"; varanother = [1, 2, 3]; functiondosomething () {console.log (something); }    functionDoanother () {Console.log (Another.join (" ! " ) ); }    return{dosomething:dosomething, doanother:doanother};} ()); foo.dosomething (); //CoolFoo.doanother ();//1! 2! 3

The module is also a normal function, so you can accept parameters:

function Coolmodule (ID) {    function  identify () {        console.log (ID);    }     return {        identify:identify    };} var foo1 = Coolmodule ("Foo 1" ); foo1.identify ();   // "Foo 1"

Module mode another simple but powerful use is to name the object that will be returned as a public API:

varFoo = (functionCoolmodule (ID) {functionChange () {publicapi.identify=identify2; }    functionidentify1 () {console.log (ID); }    functionidentify2 () {Console.log (Id.touppercase ()); }    varPublicapi ={change:change, identify:identify1}returnPublicapi;} ("Foo module") ; foo.identify (); //Foo ModuleFoo.change (); foo.identify (); //FOO MODULE

The modern modular mechanism

varMymodules = (functionManager () {varModules = {}; functiondefine (name, Deps, Impl) { for(vari = 0; i < deps.length; i++) {Deps[i]=Modules[deps[i]]; } Modules[name]=impl.apply (Impl, deps); }    functionget (name) {returnModules[name]; }    return{define:define, get:get}} ());

The core of this code is modules[name] = impl.apply (Impl, Deps). The wrapper function is introduced for the definition of the module, and the return value (module API) is stored in a list of modules that are managed by name

//Defining modules
Mymodules.define ("Bar", [],function() { functionHello (who) {return"Let me introduce:" +Who ; } return{Hello:hello};}); Mymodules.define ("Foo", ["Bar"],function(bar) {varHungry = "Hippo"; functionAwesome () {Console.log (Bar.hello (Hungry). toUpperCase ()); } return{awesome:awesome};});

// Use var bar = Mymodules.get ("bar" ); var foo = mymodules.get ("foo""Hippo" ); Foo.awesome ();

Both the Foo and bar modules are defined by a function that returns a public API. "Foo" even accepts an instance of "bar" as a dependent parameter and can use it accordingly.

JavaScript you don't know scope closure

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.