闭包理解

1.  如何产生闭包?

   *当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,产生闭包

2.  闭包到底是什么?

   * 使用Chrome调试查看

   * 理解一:闭包是嵌套的内部函数(绝大部分人)

   * 理解二:包含被引用变量(函数)的对象(极少数人)

   * 注意:闭包存在于嵌套的内部函数中

3.  产生闭包的条件?

   * 函数嵌套

   * 内部函数引用了外部函数的数据(变量/函数)

   * 执行函数定义(比如执行外部函数时)

(执行函数定义就会产生闭包,不用调用内部函数,调用外部函数时会预处理产生执行上下文,那时就可以执行内部函数的定义了)

这种函数定义,在22行就已经产生闭包。

如果把函数定义赋给变量这种形式,在22行处就不能产生闭包,因为预处理时会把fn2当做变量提升,赋值undefined,也没有执行函数定义。也就无法产生闭包。

这种方式声明的函数对象,要在26行整个函数定义执行完才会产生闭包。

 

 

常见的闭包

1. 将函数作为另一个函数的返回值

2. 将函数作为实参传递给另一个函数调用

 

看内部函数创建几次,就看外部函数执行几次。

反复执行内部函数的过程中,闭包为什么没有消失?

如果没有闭包,在执行完var f =fn1()后a就消失了,后面的f()没法从fn1里面调a。

闭包里面有msg,没有time

 

 

 

闭包的作用

1. 使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生 命周期)

2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

 

问题:

1. 函数执行完后,函数内部声明的局部变量是否还存在?

一般不存在,存在于闭包中的变量才可能存在。

(“可能”是指:闭包所在的函数对象不成为垃圾对象)

 

按理说,函数执行完后其内部的属性都会被释放,但如果该函数的某个内部函数对象通过在外部函数内return的方式赋给某个全局变量,

那么这个函数对象就存活下来了,而和它有关联的闭包里的局部变量也会存活。

2. 在函数外部能直接访问函数内部的局部变量吗?

不能。但我们可以通过闭包来让外部操作它。

(“通过闭包来让外部操作”是指:函数嵌套一个内部函数,在这个内部函数对象里写类似a++这种可以修改函数内部变量的操作,

然后把这个内部函数对象赋给外部的全局变量,就可以在外部操作函数内部的局部变量)

闭包的生命周期

1. 产生:在嵌套内部函数定义执行完时就产生了(不是在调用)

2. 死亡:在嵌套的内部函数成为垃圾对象时

闭包死亡(包含闭包的函数对象成为垃圾对象)

f = null

 

 

 

闭包应用_自定义JS模块

* 具有特定功能的js文件

* 将所有的数据和功能都封装在一个函数内部(私有的)

* 只向外暴露一个包含n个方法的对象或方法

* 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

第一种

第二种

这种直接就可以调用,比第一种更方便。

另外,压缩代码时的细节,在顶部和底部的小括号写成window。

就可以将所有window压缩成w。

 

 

闭包的缺点及解决

1. 缺点

* 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长

* 容易造成内存泄露

2. 解决

* 能不用闭包就不用

* 及时释放

f = null  //让内部函数成为垃圾对象-->回收闭包

 

 

内存溢出与内存泄露

1.内存溢出

* 一种程序运行出现的错误

* 当程序运行需要的内存超过剩余的内存时,就抛出内存溢出的错误

2.内存泄露

* 占用的内存没有及时释放

* 内存泄露积累过多了就导致内存溢出

* 常用的内存泄露:

 * 意外的全局变量(函数内不加var定义的变量)

 * 没有及时清理的定时器或回调函数(启动循环定时器后不清理)

 * 闭包(没有主动f=null让内嵌的函数对象成为垃圾对象,闭包也会一直存在)

详解JS闭包概念的更多相关文章

  1. 详解js闭包

    https://segmentfault.com/a/1190000000652891 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的 ...

  2. [转]详解JS闭包

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数 ...

  3. 详解js面向对象编程

    转自:http://segmentfault.com/a/1190000000713346 基本概念 ECMA关于对象的定义是:”无序属性的集合,其属性可以包含基本值.对象或者函数.“对象的每个属性或 ...

  4. 详解js变量、作用域及内存

    详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4       原文出处: trigkit4    基本类型值有:undefined,NUll,Boolean,Number和Strin ...

  5. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

  6. Shiro 安全框架详解一(概念+登录案例实现)

    shiro 安全框架详细教程 总结内容 一.RBAC 的概念 二.两种常用的权限管理框架 1. Apache Shiro 2. Spring Security 3. Shiro 和 Spring Se ...

  7. [转]javascript console 函数详解 js开发调试的利器

    javascript console 函数详解 js开发调试的利器   分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...

  8. 详解js和jquery里的this关键字

    详解js和jquery里的this关键字 js中的this 我们要记住:this永远指向函数运行时所在的对象!而不是函数被创建时所在的对象.this对象是在运行时基于函数的执行环境绑定的,在全局环境中 ...

  9. IPv6技术详解:基本概念、应用现状、技术实践(下篇)

    本文来自微信技术架构部的原创技术分享. 1.前言 在上篇<IPv6技术详解:基本概念.应用现状.技术实践(上篇)>,我们讲解了IPV6的基本概念. 本篇将继续从以下方面展开对IPV6的讲解 ...

随机推荐

  1. java基本数据类型和引用数据类型的调用传递的区别

    (1)基本数据类型:就是进行了值的传递把一份数据拷贝了之后传递过去 (2)引用数据类型:实际上也是进行了数据拷贝然后传过去,实际上也是值传递,只不过传递过去的值和原有的值指向了同一个对象 所以在调用的 ...

  2. Leetcode——二叉树常考算法整理

    二叉树常考算法整理 希望通过写下来自己学习历程的方式帮助自己加深对知识的理解,也帮助其他人更好地学习,少走弯路.也欢迎大家来给我的Github的Leetcode算法项目点star呀~~ 二叉树常考算法 ...

  3. 基于zookeeper实现分布式锁和基于redis实现分布所的区别

    1,实现方式不同 zookeeper实现分布式锁:通过创建一个临时节点,创建的成功节点的服务则抢占到分布式锁,可做业务逻辑.当业务逻辑完成,连接中断,节点消失,继续下一轮的锁的抢占. redis实现分 ...

  4. 阿里云域名+ 腾讯云服务器 配置nginx

    1,实现目标,通过外网访问域名,能够通过nginx 实现反向代理,以及负载均衡 2,准备工具 阿里云注册的域名: aiyuesheng.com 腾讯云领取的云服务器:centos 7 xshell 6 ...

  5. [RH134] 10-NFS和Samba客户端

    NFS和samba服务器的配置,请参考: 这里,我们只讨论客户端的使用 1.NFS客户端的使用 nfs实现的是类Unix系统之间的远程共享目录. 假设我们已经有一个提供nfs服务的服务器,IP为192 ...

  6. Java中使用RSA算法加密

    Java中使用RSA算法加密 概述 RSA加密算法是一种非对称加密算法 RSA加密的方式 使用公钥加密的数据,利用私钥进行解密 使用私钥加密的数据,利用公钥进行解密 RSA是一对密钥.分别是公钥和私钥 ...

  7. nexus Maven私服的相关配置

    Maven私服中如需本地上传Maven私服内容则需在  setting.xml中配置如下: <server> <id>nexus-releases</id> < ...

  8. idea 本地代码被覆盖问题

    一不小心误操作先执行更新操作怎么办!辛辛苦苦工作一下午的代码全被覆盖了,心里紧张死了!不过别着急,还好用的idea,请看如图操作! 1.点击鼠标右键 => 2.点击Local History = ...

  9. reuire代码优化之:r.js

    r.js是requireJS的优化(Optimizer)工具,可以实现前端文件的压缩与合并,在requireJS异步按需加载的基础上进一步提供前端优化,减小前端文件大小.减少对服务器的文件请求.要使用 ...

  10. vue+springboot后台实现页面按钮权限

    思路 1.用户跟角色关联 2.角色跟菜单关联 3.菜单跟菜单下的按钮关联 4.后端返回每个菜单下的按钮,前端通过自定义事件,在每个按钮上加上相应的事件 打字麻烦,还是看图吧! 建立btn.js 然后在 ...