博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
五个简单例子,明白闭包原理
阅读量:5124 次
发布时间:2019-06-13

本文共 1777 字,大约阅读时间需要 5 分钟。

闭包一直是许多初学者的难题,网上对闭包的讲解也是众说纷纭,但还是许多人不能明白。

下面我通过五个简单例子,让你明白闭包原理。

 

第一个例子

 第一个例子都能看懂,是个简简单单的实现 i 累加。无需多说,我们继续看第二个例子。

 

第二个例子

 

 第二个例子:我们会发现 i 这时候无法实现累加,一直显示是1。这是为什么?

---------------------------------------------------------

原因是:

1、第一个例子的 i 定义在函数外面,它在一个叫做"全局作用域"的区域里面。"全局作用域"只会在浏览器窗口关闭或页面刷新的时候进行关闭。(我们跟第二个例子对比下就知道全局作用域)。

2、第二个例子的 i 定义在函数里面,它在一个叫做"局部作用域"的区域里面。(局部作用域是我自己命名的,方便理解)。"局部作用域"会在函数被调用的时候创建,而在函数运行结束的时候关闭(并且里面创建的变量跟函数也会被删掉--垃圾回收机制)。

3、通过上面的说法:我们就知道了,第一个例子能实现累加,是因为 i 一直储存在全局作用域,没有被删掉。第二个例子,我们调用了函数,然后创建了局部作用域->定义了 i ->函数运行结束后->局部作用域关闭了,i 也被删除了。然后我们再点击, 又重新创建了局部作用域,重新定义 i 。(我们点击是在不停重新创建 i)

---------------------------------------------------------

 

问题:有没有办法让“局部作用域”不关掉呢?    -------------  那就是"闭包"了。

 

第三个例子:简单的闭包

 第三个例子: 这次还是将 i 定义到函数里面,但我们会发现,i 实现了累加。 这说明我们已经让局部作用域不关闭了,这就是简单的闭包。

我们来分析为什么局部作用域没有被关闭:

①我们在函数内部定义了 i

②定义了函数 add2(),并且在add2()引用了 i

③最后return add2。

④(要注意的是:这里document.οnclick=add1();  并不是调用add1函数[调用是不加括号],而是让add1()执行了,获取到了add1() 的值)。 其实相当于 documen.onclick = add2  //不能直接这么写,为了方便理解,我们假设它存在 ;  

⑤ 这时就会神奇的发现,我们竟然可以在全局环境中使用在函数里面定义的函数。(一般情况下,全局环境无法使用函数里面定义的变量,就是你在函数外面无法使用函数里面定义的变量,[函数里面定义的变量同理])。

⑥ 因为documen.onclick = add2;的存在(作用域链的存在,我会在另一篇文章中分析作用域链),add2的执行依赖add1()里面定义的 i,使得add1()不会被关闭,i 也不会被重新定义,累加的值也被成功的保存下来。

 

第四个例子:简写闭包

 

 第四个例子:这里涉及到“匿名函数自执行”。(function(){})();  一般执行函数是在函数名后面加括号,这里(function(){})相当于一个表达式,我们在它后面加();  。就相当于执行了这个函数。  同样的,我们 return function(){};  。 也是把这个函数返回出去了,只不过返回出去一个匿名函数。

 

第五个例子:闭包的作用。

 

  第五个例子:有蛮多初学者说,都听别人闭包好用,可是不知道他的实际应用。像第五个例子,我在全局也定义了一个 i ,也对它进行了控制台输出,发现我们闭包里的函数并不会对全局造成影响,却实现了全局的效果。对于比较大型的合作项目,很多人分工合作,如果每个人都在全局定义变量 ,如果定义了同样名字的变量,对这两个人的程序都会造成一些影响。 这就是闭包。

闭包的用处还很多,明白了原理,你可以继续挖掘它。

 

还有点需要注意的是:闭包的存在会使得他不会被垃圾回收机制回收,他会比其他函数占更多的内存,过渡使用闭包可能会导致内存占用过多。可能会导致浏览器崩溃的问题。解决方法就是已经达到我们的目的的时候,解除对匿名函数的引用,没有了引用变成了普通函数,被垃圾回收机制回收。

转载于:https://www.cnblogs.com/wdz-freddy/p/7570175.html

你可能感兴趣的文章
图片等比例缩放及图片上下剧中
查看>>
【转载】Linux screen 命令详解
查看>>
background-clip,background-origin
查看>>
Android 高级UI设计笔记12:ImageSwitcher图片切换器
查看>>
【Linux】ping命令详解
查看>>
对团队成员公开感谢博客
查看>>
java学习第三天
查看>>
python目录
查看>>
django+uwsgi+nginx+sqlite3部署+screen
查看>>
Andriod小型管理系统(Activity,SQLite库操作,ListView操作)(源代码下载)
查看>>
在Server上得到数据组装成HTML后导出到Excel。两种方法。
查看>>
浅谈项目需求变更管理
查看>>
经典算法系列一-快速排序
查看>>
设置java web工程中默认访问首页的几种方式
查看>>
ASP.NET MVC 拓展ViewResult实现word文档下载
查看>>
8、RDD持久化
查看>>
第二次团队冲刺--2
查看>>
VMware Tools安装
查看>>
Linux上架设boost的安装及配置过程
查看>>
[转载]加密算法库Crypto——nodejs中间件系列
查看>>