JS闭包的基础知识,闭包的本质,闭包的作用,闭包的间谍属性和闭包的遗憾

Posted 风意不止

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS闭包的基础知识,闭包的本质,闭包的作用,闭包的间谍属性和闭包的遗憾相关的知识,希望对你有一定的参考价值。

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),这时一定要小心,不要随便改变父函数内部变量的值。

暂时先总结到这里吧。还有一些,也会在本文继续修改更新

以上是关于JS闭包的基础知识,闭包的本质,闭包的作用,闭包的间谍属性和闭包的遗憾的主要内容,如果未能解决你的问题,请参考以下文章

JS闭包的理解

JS重要知识点总结-不完善

js闭包

JS详细图解作用域链与闭包

个人对js闭包的心得见解

了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化