前言
闭包(closure)是 JavasSript 的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。每个前端工程师都应该能够对闭包的原理烂熟于心,看完这篇文章,相信同学们对闭包一定会有更深的理解
正文
什么是闭包?
闭包是指有权访问另一个函数作用域中的变量的函数,因为javaScript有一个特别之处,子对象只会一级一级向上查找搜索父对象的变量,也就是说子对象可以访问父对象的变量,但是父对象不可以访问子对象的变量。所以,如果你希望访问一个函数的作用域,你只能在它的作用域下访问,或者在这个函数的作用域下再定义一个函数,这也就是“闭包”
为什么要用闭包
闭包可以用在许多地方。它的最大用处有两个,一个是上一小节提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在 父类调用后被自动清除。一般来说,当函数执行完毕后,局部活动对象会被销毁,内存中仅保存全局作用域。但是闭包的情况有所不同。
在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域中,所以即使闭包的函数执行完毕以后,它的作用域链仍然在引用这个活动对象,所以它的活动对象仍然会留在内存中。由于闭包会携带包含它的函数的作用域,也因此会占用更多的内存
匿名函数与闭包的区别
很多同学在初学前端的时候可能分不清匿名函数和闭包,其实这两者的确半毛钱关系都没有。匿名函数就是没有名字的function,常用于自执行函数,而闭包是指有权访问函数作用域中的变量的函数。匿名函数可用于实现闭包。
但是上面这个例子并不能说明匿名和闭包有啥关系,只能说明匿名可以用于
实现闭包,仅此而已,闭包机制适用于所有的javaScript函数,无论是否是匿名的
闭包中的变量问题
闭包的作用链机制引出了一个副作用,闭包只能取得包含函数中任何变量的最后一个值,因为闭包所保存的是整个变量对象,而不是某个特殊变量
这个函数会返回一个函数数组,每个函数的返回值都是10,而不是位置0返回0,位置1返回1,因为这些函数都是闭包的函数,作用域链中保存着createFunctions()函数的活动对象,所以它们引用的都是一个值,也就是10
内存泄露
如果闭包的作用域中保存着一个HTML元素,那么就意味着改元素无法被销毁,因为这个HTML元素的引用一直存在,闭包就不会回收,即使执行完毕。
所以有必要把ele变量设置为null,就可以解除引用。顺利减少其引用数,确保正常回收其站的内存
小结
1、在后台执行环境中,闭包的作用域链包含着它自己的作用域、包含函数的作用域和全局作用域。
2、当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止。
小伙伴们今天的学习就到这里了,如果觉得本文对你有帮助的话,欢迎转发,评论,收藏,点赞!!!