js全局变量和局部变量名称一样_详解JS闭包概念

闭包理解

1. 如何产生闭包?
* 当一个嵌套的内部 ( 子 ) 函数引用了嵌套的外部 ( 父 ) 函数的变量 ( 函数 ) 时,产生闭包
2. 闭包到底是什么?
* 使用 Chrome 调试查看
* 理解一:闭包是嵌套的内部函数 ( 绝大部分人 )
* 理解二:包含被引用变量 ( 函数 ) 的对象 ( 极少数人 )
* 注意:闭包存在于嵌套的内部函数中
3. 产生闭包的条件?
* 函数嵌套
* 内部函数引用了外部函数的数据 ( 变量 / 函数 )
* 执行函数定义 ( 比如执行外部函数时 )

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

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

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

这种方式声明的函数对象,要在 26 行整个函数定义执行完才会产生闭包。
常见的闭包
1. 将函数作为另一个函数的返回值
2. 将函数作为实参传递给另一个函数调用
看内部函数创建几次,就看外部函数执行几次。
反复执行内部函数的过程中,闭包为什么没有消失?
875c8a65fa98d1d9a0da5d8a56ac6c79.png
如果没有闭包,在执行完 var f =fn1() 后 a 就消失了,后面的 f() 没法从 fn1 里面调 a 。
c232a48220aa11b7586225114a6da373.png

闭包里面有 msg ,没有 time

闭包的作用

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

2. 让函数外部可以操作 ( 读写 ) 到函数内部的数据 ( 变量 / 函数 )
问题:
1. 函数执行完后,函数内部声明的局部变量是否还存在?
一般不存在,存在于闭包中的变量才可能存在。
( “可能”是指:闭包所在的函数对象不成为垃圾对象 )

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

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

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

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

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

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

72d75e67ee92277ec174fa4918a5da3e.png
闭包的生命周期
1. 产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
2. 死亡:在嵌套的内部函数成为垃圾对象时

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

f = null

闭包应用 _ 自定义 JS 模块
* 具有特定功能的 js 文件
* 将所有的数据和功能都封装在一个函数内部(私有的)
* 只向外暴露一个包含 n 个方法的对象或方法
* 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
第一种
0b9d693eff336d3cf4cd7ef230f1dc0e.png
dc361a28e9c89889c39965e347b7f743.png

第二种

3ae2465e364442326faac66024961faa.png
c0694f64429de562a14898b0f826f07d.png
这种直接就可以调用,比第一种更方便。
另外,压缩代码时的细节,在顶部和底部的小括号写成 window 。
就可以将所有 window 压缩成 w 。
闭包的缺点及解决
1. 缺点
* 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
* 容易造成内存泄露
2. 解决
* 能不用闭包就不用
* 及时释放
f = null // 让内部函数成为垃圾对象 --> 回收闭包
内存溢出与内存泄露
1. 内存溢出
* 一种程序运行出现的错误
* 当程序运行需要的内存超过剩余的内存时,就抛出内存溢出的错误
2. 内存泄露
* 占用的内存没有及时释放
* 内存泄露积累过多了就导致内存溢出
* 常用的内存泄露:
* 意外的全局变量(函数内不加 var 定义的变量)
* 没有及时清理的定时器或回调函数(启动循环定时器后不清理)
* 闭包(没有主动 f=null 让内嵌的函数对象成为垃圾对象,闭包也会一直存在)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值