最简单的例子让你轻松理解JavaScript闭包

关于闭包

在理解闭包之前,为了让大家更好的理解闭包,我举一个形象的例子。在JS里有着作用域的概念,那么作用域是什么呢?有什么用呢?下面这个例子能形象的体现
比如每一座城市,城市里乡镇啊有公园,超市等,这些建筑设施就构建了这一个城市(环境),那么这些环境构成的依据是什么呢?是有人依赖它,用它。当这个城市的的人迁出这个城市,那么这个城市没有人再依赖他,那么它的存在就没有意义了,

总的来说当这个城市(环境)不再被需要,它就被回收销毁掉,环境存在的前提是被需要

举一个例子,下面代码中,重复调用能实现输出num的累加吗?

function fn1(){    
	var num = 1;
	
	function fn2(){
	console.log(++num);  
	}
	fn2()
}
fn1()
			/*如果要实现num的累加,重复调用能实现吗*/

在这里插入图片描述答案是不能的
在这里入图片描述为什么不能实现呢?上面我画了一个函数在内存空间中的变化模拟图

  1. 在定义一个函数的时候,函数会在堆内存中开辟一个存储空间,把存储地址给到函数名,此时函数名存储在栈内存中
  2. 此时我们调用函数,函数就会开辟一个执行空间(我们管这个空间叫做闭包空间),执行空间执行完以后就会销毁,以此类推,开辟一个执行完以后销毁一个,就像我们刚刚数说的,环境存在的前提是被需要,因为执行完,已经没有用了,js就会把它当作垃圾回收了
  3. 那么这样就很好理解了,此时重复调用,为什么不能实现num的累加,因为每一次调用函数,函数开辟新的一块空间,执行完以后又进行销毁,变量num已经不存在了,下一次调用又开辟一个新的执行空间,执行完之后又销毁…

怎么样才能让执行空间不销毁,实现num的累加呢?

那么我们接下来看以下代码

function fn1(){
	var num = 1;
	
	return function fn2(){
	console.log(++num);
	}
	
}	
var a = fn1();
a();
a();
a();

在这里插入图片描述那么我此时我们再来看看函数空间在内存中的变化
在这里插入图片描述

  1. 此时外部有变量接收函数fn1内返回的fn2函数,此时就形成了我们所说的(环境被需要),那么函数fn1的执行空间就不会被销毁,此时变量num就一直存在这个函数空间里,所以形成了变量生命周期延长这么一个效果
  2. 此时的外部全局中的变量a就是接收到返回的函数fn2,每次a()调用都是调用fn2函数,所以最后就可以实现num的累加啦。

形成闭包总结:

  1. 以上面例子为例,函数fn1返回函数fn2,此时fn2就是fn1的闭包函数
  2. 函数fn1外部有一个变量接收着返回的函数

闭包的特点:

  1. 可以实现变量生命周期延长,就刚刚这个例子,闭包空间没销毁,变量num就还一直存在
  2. 函数外部可以访问函数内部私有变量
  3. 保护私有变量(只要是函数都有这个特点)

当然了闭包也有许多它的缺点,关于闭包的理解咱们就讲到这

发布了1 篇原创文章 · 获赞 5 · 访问量 93

猜你喜欢

转载自blog.csdn.net/weixin_45717379/article/details/104437915