"You do not know JavaScript (a)" Notes - Scope closure

When the function can remember where and when access lexical scope, it creates a closure, even if the function is executed outside of the current lexical scope.

function wait(message) {
    setTimeout( function timer() {
        console.log( message );
    }, 1000 );
}

wait( "Hello, closure!" );

An internal function (called timer) is passed to setTimeout (..). the wait timer having a cover (..) the scope of the closure, and therefore also retain references to the variable message. After the wait (..) performs 1000 milliseconds, its scope and the interior not disappear, still retain the wait Timer function (..) closure scope.
Deep into the inner workings of the engine, the built-in tools function setTimeout (..) to hold a reference to the argument, this parameter is called fn or perhaps func, or other similar names. Engine will call this function, that is, the internal timer function, and lexical scoping remain intact in the process in the case. This is a closure.

In the timer event listener, Ajax request, cross-window communication, Web Workers, or any other asynchronous (or synchronous) tasks, just use the callback function, it is actually in use closures!

Module mode

Another advantage of the closure code patterns - Module

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(); // cool
foo.doAnother(); // 1 ! 2 ! 3

First, CoolModule () is just a function must be to create a module instance by calling it. If you do not execute external functions, scope and internal closures can not be created.
Objects represented: {value, ... key} Next, CoolModule () returns an object-literal syntax. Returns this object contains references to the function rather than the inside of the internal data variables. We keep internal data variables are hidden and private status. This can be seen as an object type of the return value is essentially the module public the API .
The return value of the final object type is assigned to the external variable foo, then it can be accessed by the properties of the API methods, such foo.doSomething ().

Thus block pattern requires two necessary conditions:

  1. There must be an external closed function, which must be called at least once (each call will create a new module
    instance).
  2. Blocking function must return the at least one internal function, so that the internal function can be formed in the closures private scope, and
    and may be private access or modify state.

Another simple but powerful module mode change usage is named public API as an object to be returned:

var foo = (function CoolModule(id) {
    function change() {
        // 修改公共 API
        publicAPI.identify = identify2;
    }
    function identify1() {
        console.log( id );
    }
    function identify2() {
        console.log( id.toUpperCase() );
    }
var publicAPI = {
    change: change,
    identify: identify1
};
    return publicAPI;
})( "foo module" );

foo.identify(); // foo module
foo.change();
foo.identify(); // FOO MODULE

, May be performed by leaving the internal public API object reference example inside the module from the inside of the module instance to modify, add or delete include methods and properties, and modify their values.

Modern module mechanism

Most rely loader module / module definition are encapsulated in such a nature friendly Manager API.

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};
})();

This code is the kernel modules [name] = impl.apply (impl, deps). To define the function module introduces package (any dependency can be passed), and the return value, which is the API module, a module is stored under the name in the list to manage.

Here's how to use it to define the module:

MyModules.define("bar", [], function () {
    function hello(who) {
        return "Let me introduce: " + who;
    }
    return {hello: hello};
});

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 introduce: hippo
foo.awesome(); // LET ME INTRODUCE: HIPPO

"Foo" and "bar" module is returned through a public API function defined. "Foo" even accept exemplary "bar" as dependent parameters, and it can be used accordingly.

Guess you like

Origin www.cnblogs.com/simpul/p/11027204.html