闭包

作者: 饥人谷_御风 | 来源:发表于2017-12-13 22:52 被阅读0次

闭包

闭包是什么?

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行,简单上讲,就是在一个函数中内部的函数。

function foo() {
var a = 2;
function bar() {
console.log( a );
}
return bar;
}
var baz = foo();
baz(); // 2 —— 朋友,这就是闭包的效果。

那么bar函数就是一个闭包,它可以在作用域外被访问。
各种闭包实例:

function foo() {
var a = 2;
function baz() {
console.log( a ); // 2
}
bar( baz );
}
function bar(fn) {
fn(); // 妈妈快看呀,这就是闭包!
}
function setupBot(name, selector) {
$( selector ).click( function activator() {
console.log( "Activating: " + name );
} );
}
setupBot( "Closure Bot 1", "#bot_1" );
setupBot( "Closure Bot 2", "#bot_2" );
function wait(message) {
setTimeout( function timer() {
console.log( message );
}, 1000 );
}
wait( "Hello, closure!" );

本质上无论何时何地,如果将函数当作第一级的值类型并到处传递,就会由闭包,在定时器、事件监听器、Ajax请求、跨窗口通信、Web Workers或者其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是闭包

模块

模块实例:

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

这种模式在JavaScript中就是模块。
最常见的实现模块模式的方法通常被称为模块暴露
模块模式所具备的两个必要特点:

必须有外部的封闭函数,该函数至少被调用一次(每次调用都会产生新的模块实例)。
封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。

模块模式的另一个简单但强大的用法是命名将要作为公共API返回的对象。

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

通过在模块实例的内部保留对公共API对象的内部引用,可以从内部对模块实例进行修改,包括添加或删除方法和属性,以及修改他们的值。
现代的简单模块机制:

var MyModules = (function Manager() {
            var modules = {}

            function define(name, argus, func) {
                for (var i = 0; i < argus.length; i++) {
                    argus[i] = modules[argus[i]]
                }

                modules[name] = func.apply(func,argus)
            }

            function get(name) {
                return modules[name]
            }

            return {
                define: define,
                get: get
            }
        })()

        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.call(undefined, "hippo")
        ); // Let me introduce: hippo
        foo.awesome.call(undefined); // LET ME INTRODUCE: HIPPO

"foo"和"bar"模块都是通过一个返回公共API的函数来定义的,“foo”甚至接受“bar”的实例作为依赖参数,并能相应的使用它。
它们符合前面列出的模块模式的两个特点:调用包装了函数定义的包装函数,并且将返回值作为该模块的API。

ES6的模块机制
ES6中为模块增加了一级语法支持。在通过模块系统进行加载时,ES6会将文件当作独立的模块来处理。每个模块都可以导入其他模块或特定的API成员,同时也可以导出自身的API成员。
重构之前的模块得三个文件

  1. bar.js
         function hello(who) {
             return "Let me introduce: " + who
         }
         export hello
  1. foo.js
         import hello from "bar"
         var hungry = "hippo"
         function awesome() {
             console.log(hello(hungry).toUpperCase())
         }

         export awesome
  1. baz.js
         module foo from "foo"
         module bar from "bar"
         console.log(bar.hello("hippo"))
         foo.awesome

import方法:将一个模块中的一个或多个API导入到当前作用域中,并绑定在一个变量上。
module方法:将整个模块的API导入并绑定到一个变量上
export方法:将当前模块的一个标识符导出为公共API
模块文件中的内容会被当作包含在作用域闭包中一样来处理。

相关文章

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

  • 闭包(closure)

    ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...

  • swift- 闭包一

    /*• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包*/

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • Swift-进阶 :闭包(二)逃逸闭包 & 非逃逸闭包

    本文主要分析逃逸闭包 、非逃逸闭包、自动闭包 逃逸闭包 & 非逃逸闭包 逃逸闭包定义 当闭包作为一个实际参数传递给...

  • javascript闭包详解

    跟我念 bi 闭 bao包 ,闭包的闭,闭包的包。。 闭包的简介 在计算机科学中,闭包(英语:Closure),又...

网友评论

      本文标题:闭包

      本文链接:https://www.haomeiwen.com/subject/gcltwxtx.html