JS闭包总结来源和扩展知识来自于:
1.简书:彻底搞懂JS闭包各种坑2.百度百科 闭包
闭包不是JS独有的特性。但本文以JS闭包来了解闭包的。
1.闭包的本质:是一个函数。
2.闭包的作用:间谍作用,延长变量生命周期。
3.闭包的构成模型:A函数,内部有一个间谍B函数,B函数能访问A函数的私有变量,并返回给A函数外部一些数据。这里的B函数,就叫做闭包。
4应用场景
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
以上两点是闭包最基本的应用场景,很多经典案例都源于此。
5.回收机制
参数和变量不会被垃圾回收机制回收
在Javascript中,如果一个对象不再被引用(注意这里写的不是调用,调用和引用是两回事。调用是运行,引用是引用地址),那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
function a(){ var x=1 return function b(){ var y=1 console.log(x++) //间谍闭包,拉拢了外部的变量x,使用后++,返回原值再增加 console.log(y++) //间谍闭包,使用了内部了变量y,使用后++,返回原值再增加 } } //console.log(x), 这时候会报错,外部无法直接访问x。使用闭包,就可以间接的访问x了。 //a(),直接运行a,会返回,return之后的,闭包函数代码 function b(){....} //b(),直接使用闭包,也会报错,因为无法直接使用闭包,必须使用a才能访问b //所以,b是一个技术很水的间谍,无法跟外部直接沟通。所以b叫做外交部长,更合适点吧。 var c=a() //创建一个全部变量C,来引用b,只有通过运行a()才能调用b函数。 //可以使用a()().这里为了方便使用c代替a() c() //这里执行了闭包函数b,结果为1 1,这里a中的x被修改成了2。 setTimeout(c(),5000) // 延迟5秒,再执行一次,看看如何,发现x依然在内存中,y不在内存中,结果 2 1 c() //这里再次执行了闭包函数。也就是return后面的函数。执行结果3 1 //a和b一直存在内存中的原因:C是全局变量,生命周期很长。C引用a()的地址,所以a()执行一次,计算结果是b所以b也一直在内存中。 //x在内存,y不在内存的原因:间谍函数b的小算盘:x在b的外部,不牵制住,就会丢掉。y在b的内部,可以随时创建
6.使用注意点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
暂时先总结到这里吧。还有一些,也会在本文继续修改更新
原文地址:https://www.cnblogs.com/cn-oldboy/p/12350627.html