闭包

作者: 糕糕AA | 来源:发表于2019-06-27 14:14 被阅读0次

什么是闭包

  • 就是在一个外部函数内部创建另一个函数

  • 全局调用内部函数的时候可以访问到外部函数的局部变量,并使用!

闭包的使用场景:

  • setTimeout

  • 回调

  • 封装变量

  • 事件处理程序

  • 模块模式

优缺点:

  • 逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑

  • 方便调用上下文的局部变量。

  • 加强封装性,是第2点的延伸,可以达到对变量的保护作用。

  • 延长作用域链:局部变量存在函数中,函数使用完后,局部变量会自动释放,闭包后,局部变量还存在被调用的可能,没有被及时释放,作用域链延长。

闭包会使得函数中的变量都被保存在内存中,内存消耗很大,在IE中可能导致内存泄露。 (动态存储分配函数内存空间,在使用完毕后未释放,导致一直占用该内存单元,直到程序结束)

- 垃圾清除

  1. 标记清除(常用):垃圾回收机制在运行时会给存储在内存中的所有变量加上标记(可以使用任何标记方式)。然后去掉环境中的变量和被环境变中的变量引用的变量的标记。而在此之后被加上标记的变量被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后垃圾收集器完成内存清除工作,销毁带标记的值并回收他们所占用的内存空间

  2. 引用计数:reference counting 含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数为1.如果同一个值又被赋给另一个变量,引用次数加1.相反的,变量包含这个值得引用变量又取得另一个值,则这个值的引用次数减1.当引用次数为0时,将其占用内存回收。(循环引用的变量和函数无法回收)

  3. 解决:将完成的函数或变量重置为null。

闭包的模块应用分析

在 JavaScript 中,闭包最常见的应用是模块模式。模块允许你定义外部不可见的私有实现 细节(变量、函数),同时也可以提供允许从外部访问的公开 API。

function User(){    
    var username, password; 
 
    function doLogin(user,pw) {       
        username = user;         
        password = pw; 
 
        // 执行剩下的登录工作    
    }    
    var publicAPI = {      
        login: doLogin  
    }; 
 
    return publicAPI;
} 
 
// 创建一个User模块实例
var fred = User();  // 。User() 只是一个函数,而不是需要实例化的类,所以只是正常调用就可 以了。使用 new 是不合适的,实际上也是浪费资源。
 
fred.login( "fred", "12Battery34!" );
// 函数User() 用 作 外 层 作 用 域, 持 有 变 量username 和 password,以及内层的函数 doLogin();这些都是这个 User 模块私有的内部细节,无法从外部访问。

执行 User() 创建了 User 模块的一个实例,这创建了一个新的作用域,因而创建了所有内 层变量 / 函数的一个新副本。我们将这个实例赋给 fred。如果再次运行 User(),那么会得 到一个不同于 fred 的全新实例。

内层的函数 doLogin() 在 username 和 password 上有一个闭包,这意味着即使在 User() 函 数运行完毕之后,函数 doLogin() 也保持着对它们的访问权。

publicAPI 是带有一个属性 / 方法 login 的对象,login 是对内层函数 doLogin() 的一个引 用。当我们从 User() 返回 publicAPI 时,它就变成了我们命名为 fred 的那个实例。

此时,外层的函数 User() 已经运行完毕。我们通常认为像 username 和 password 这样的内 层变量也就随之消失了。但上述示例并不会这样,因为 login() 函数的内部有一个可以使 得它们依然保持活跃的闭包。

这就是我们可以调用 fred.login(..) 的原因,这等同于调用内层 doLogin(..),并且 fred. login(..) 仍然可以访问内层变量 username 和 password。

相关文章

  • 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/kbfrcctx.html