闭包

定义:闭包就是允许使用内部函数,也就是说在函数定义和函数表达式位于另一个函数的函数体内的时候,而且这些内部函数可以访问他们所在的外部函数中声明的所有的局部变量,参数和声明的其他内部函数。当其中一个这样的内部函数在包含他们外部函数之外被调用的时候在这个时候就会形成闭包。也就是说内部函数会在外部函数返回后被执行而当这个内部函数执行时,他仍然必须访问其外部函数的局部变量 参数以及其他内部函数 这些局部变量 参数和函数声明的值是外部函数返回的值 但也会受到内部函数的影响。
1.变量作用域
变量的作用域分为全局变量和局部变量
javascript语言的特别之处就在于函数内部可以直接读取到全局变量,但是在函数外部无法读取函数内部的局部变量,
注意:在函数内部声明变量的时候一定要使用var命令如果不使用的话你就声明的是一个全局变量
2.如何从外部读取到函数内部的局部变量?
处于各种原因我们有时候需要获取到函数内部的局部变量但是正常情况下是不能的只有在函数的内部再定义一个函数才可以
function f1(){
var n=00
function f2(){
alert(n)00
}
}
在上面的代码中函数f2就被包括在函数f1中在这个时候f1内部的所有局部变量对f2都是可见的但是反过来就不行,f2内部的局部变量对f1就是不可见的
这就是javascript语言特有的链式作用域结构,子对象会一级一级的向上寻找所有父对象的所有变量对子对象都是可见的反之则不成立,
既然f2可以读取到f1中的局部变量那么只需要把f2作为返回值我们就可以在f1外部读取到他的内部变量;
闭包的用途
闭包他可以用到许多的地方,他最大的用处用两个,一个是前面提到的可以读取到函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除
原因:原因就在于f1是f2的父函数而f2被赋了一个全局变量,这导致f2始终在内存中而f2的存在依赖于f1因此f1始终也在内存中不会在调用结束后被垃圾回收机制回收
垃圾回收:具有自动垃圾回收机制,垃圾收集器会按照固定的时间间隔周期性的执行
js中最常见的垃圾回收方式是标记清除
原理:当变量进入环境时将这个变量标记为进入环境。当变量离开环境时则将其标记为离开环境,标记离开环境的时候就回收内存
工作流程:
1.垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。
2.去掉环境中的变量以及被环境中的变量引用的变量标记
3.再被加上标记的会被视为删除的变量
4.垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的空间
引用计数的方式:
原理 跟踪记录每个值被引用的次数
工作流程:
1.声明了一个变量并且讲一个引用类型的值赋给这个变量,这个引用类型值的引用次数就是1
2.同一个值又被赋值给另一个变量这个引用类型值的引用次数加一
3.当包含这个引用类型值的变量有被赋值给另一个值了那么这个引用类型的值引用次数减一
4.当引用次数变成0时说明没办法访问这个值了
5.当垃圾收集器下一次运行时就会释放引用次数是0的值所占的内存
闭包的优点:
逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑
方便调用上下文的局部变量
使用闭包的注意点、(缺点)
1.由于闭包会使得函数中的变量都被保存到内存中,内存消耗很大所以不能滥用闭包,否则会造成网页的性能问题在IE中可能导致内存泄漏解决办法是退出函数之前将不使用的局部变量全部删除
2.闭包会在父函数外部,改变父函数内部变量的值,所以如果你把父函数当作作对象使用,把闭包当做她的公用方法,把内部变量当作他的私有属性,这时不要随便改变父函数内部变量的值
使用场景
1.采用函数引用方式的setTimeout调用
2.将函数关联到对象的实例方法
3.封装相关的功能集

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值