JavaScript Basics – Closures

Source: Internet
Author: User
Tags closure

JavaScript Basics – Closures

Understanding the concept of closures is important for learning JavaScript, many novice (including me) began to learn the closure, will feel indefinitely, before looking at some information, organized a closure of a blog, if there is negligence and error, I hope that we have a lot of advice.

Overview

Understanding the concept of closures, we recommend that you first recall the relevant knowledge of the JS scope, if you have questions about the classmate, you can refer to: JavaScript base – scope. Closures are defined as follows:

Closure is when a function was able to remember and access it lexical scope even when this function is executing outside I TS lexical scope.

The free translation is that when a function is executed outside its lexical scope, it can still access variables in its lexical scope. The "lexical scope" here is the scope that we generally understand.

Let's start with an example.
Eg1

function foo () {    var a = 2;    function Bar () {        console.log (a);     }    Bar ();} Foo (); -2

In the above example, when the function is called bar() , the a value of the variable is taken from the scope of the function, that is, foo bar() the upper scope of the function, from the concept of closure, this example basically belongs to a closure. Why is it "basic", because it a is actually a bar() variable on the scope chain of a function, we call it a nested scope more. Let's look at one more example:
Eg2

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

 

The EG2 example might be more likely to embody the concept of closures: when we define foo() a function, we return a function, assign a reference to the var test = foo(); function test , and then, when we execute the test(); statement, we find that a the value is still available, and we call it bar() a closure.

Closure principle: When the compiler executes var test = foo(); , it identifies it as a closure, and the garbage collector retains the scope chain of the closure when it reclaims memory. So test() at runtime, you can access the lexical scopes defined by the closures.

function settimeout ()

In fact, when we write the JS code, we often use closures, but we do not realize that, for example setTimeout() :
Eg3

function Wait (message) {    setTimeout (function timer () {        console.log (message);    }, 1000);} Wait ("Hello, closure!");

I believe that the students have more or less used setTimeout() , in the eg3 we pay careful attention, we can find that our definition in wait() the anonymous function is deferred operation, but it can still access to the variable message . The concept of the closure of the control, is not clear. Similarly, when we define many asynchronous functions, we use closures. is not found in the closure of the fact that we are always in use.

Closures in the loop

Let's start by looking at an example.
Eg4

for (var i=1; i<=5; i++) {    setTimeout (function timer () {        console.log (i);    }, i*1000);}

What do you think will be entered in EG4? Is it 1,2,3,4,5? If you assign the code to the browser console panel, you may be disappointed that the code output is 6,6,6,6,6; Do many students think that each one i is not running alone? How the output is all 6.

Before analyzing this example, we have a concept in mind: JS is applied to function scopes, not block-level scopes. Reflected in the EG4, is the circulation of the use of the i public. So at the timer() time of execution, i it has become 6.

If JS Iife (execute function immediately) is applied, will the output be 5 6? Like what:
Eg5

for (var i=1; i<=5; i++) {    (function () {        setTimeout (function timer () {            console.log (i);        }, i*1000 );    }) ();}

We can test it, and the result is 6,6,6,6,6. Or does anyone think that if the delay time is shortened enough, the result will be normal? The actual results may disappoint you. Even if we set the delay time to 0, the result is the same, because the for execution efficiency is inherently setTimeout() higher, and setTimeout() how to shorten the delay time for .

In order to achieve our desired results, the solution is to bring each loop into i time() the scope, such as:
Eg6

for (var i=1; i<=5; i++) {    (function () {        var j = i;        SetTimeout (function timer () {            console.log (j);        }, j*1000);    }) ();}

Or is:
Eg7

for (var i=1; i<=5; i++) {    (function (j) {        setTimeout (function timer () {            console.log (j);        }, j* );    }) (i);}

extension : The introduction let of keywords in ES6, and the purpose is to implement block-level scope in JS, so the code in EG5 can also be modified to:
Eg8

for (var i=1; i<=5; i++) {let    j = i;     SetTimeout (function timer () {        console.log (j);    }, j*1000);}

Or
Eg9

for (let I=1; i<=5; i++) {    setTimeout (function timer () {        console.log (i);    }, i*1000);}
Closure Applications – modules (module)

Modules are typical examples of application closures, let's look at an example:
Eg10

function Coolmodule () {    var something = "cool";    var another = [1, 2, 3];    function dosomething () {        console.log (something);    }    function Doanother () {        Console.log ("Another.join ("! "));    }    return {        dosomething:dosomething,        doanother:doanother    };} var foo = coolmodule (); foo.dosomething (); Coolfoo.doanother (); 1! 2! 3

In Eg10 CoolModule is a function that returns a value of one object, then a foo closure is doSomething doAnother generated when called and. This is the module simplest example of using closures, so let's look at an example of how to resolve module dependencies.
Eg11
Defining the implementation of a dependent module

var mymodules = (function Manager () {    var modules = {};    function define (name, Deps, Impl) {for        (var i=0; i<deps.length; i++) {            deps[i] = modules[deps[i]];        }        Modules[name] = impl.apply (Impl, deps);    }    function get (name) {        return modules[name];    }    return {        define:define,        get:get    };}) ();
 

Let's analyze the above code. First, an empty object is defined, and module then the function is defined, with three parameters: defining the name of the module, defining the module's define name dependencies, deps impl and defining how the module is implemented.

 
Mymodules.define ("foo", ["bar"], function (bar) {    var hungry = "Hippo";    function Awesome () {        console.log (Bar.hello (Hungry). toUpperCase ());    }    return {        awesome:awesome    };}); var bar = mymodules.get ("bar"), var foo = mymodules.get ("foo"), Console.log (    Bar.hello ("Hippo"));/Let me introd Uce:hippofoo.awesome (); Let ME Introduce:hippo

Of course ES6 also introduced the module, making the call more convenient, look directly at the example bar
Eg12
Bar.js

function Hello (WHO) {    return ' let me introduce: ' + Who;} Export Hello;

Foo.js

Import only ' hello () ' from the ' bar ' Moduleimport Hello from "bar", var hungry = "Hippo"; function awesome () {    consol E.log (        hello (hungry). toUpperCase ()    );} Export awesome;

  

Import the entire "foo" and "Bar" Modulesmodule foo from "foo", module bar from "Bar", Console.log (    Bar.hello ("Rhino " )); Let me Introduce:rhinofoo.awesome (); Let ME Introduce:hippo

Note There are two ways to call module in Eg12, respectively, import and module , the former is the interface, and the latter calls the module, the usage is slightly different, the former is the direct interface itself hello(hungry) , and the latter is the method in the calling module bar.hello("rhino") .

Reference documents
    • You-dont-know-js

JavaScript Basics – Closures

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.