关于javascript闭包(Closure)和return之间的暧…

2018-12-02 06:15:03来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

  什么是闭包?阮一峰老师说的很清楚了,定义在一个函数内部的函数,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

  首先要了解Javascript的变量作用域:全局变量局部变量。全局嘛,就是共享,任何一个函数内部可以直接读取全局变量;局部嘛,就是私有,不暴露在外的。如何判断该变量是全局还是局部,函数内部看它有没有var进行声明。没有var声明的变量,实际是个全局变量,别被骗咯!

傲娇的小眼神(别被骗咯)

  Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。既然子对象可以读取父对象的变量,那我们想获取一个对象(假设为f1)里面的变量,给f1创建一个子对象(假设为f2),并将子对象return出去,不就可以在外部访问到这个对象(f1)的私有变量。f2就是闭包,没错,它就是闭包。不多说,代码如图:

f2即为闭包

  那么问题来了,你说闭包是为了获取一个函数内部的私有数据而创建的,那我直接将一个想要获取的数据return出去,外部不一样可以获取嘛,不多说,看权威的jquery源码:

我非要return

外部访问数据

  也有人说闭包可以防止全局变量污染,什么是全局变量污染?当多人一起开发一个大型项目的时候,每个人负责一块,其中定义的全局变量可能会存在命名冲突,当项目进行整合的时候起冲突的全局变量会被覆盖,这应该很好理解。闭包的应用将变量私有化,可以起到防止变量全局污染的作用,外部同时也可以访问到私有化的变量。解决全局变量污染的问题,可以结合js模块化开发思维,如下图:

js模块化一

js模块化二(闭包)

  两者的区别在图片中已经阐明了,可以自行试一试。闭包还有一个比较大的用处,相信你们都知道,让这些变量的值始终保持在内存中。所以注意的一点就是:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。(阮一峰老师原话,偷点懒0.0)。

  这句话不知道你们能否了解,我简单阐述下我的想法,一定要认真看完哈!首先全局变量和局部变量生命周期是不同的,全局变量存放在一个区域内,具有全局作用域;局部变量放在堆栈中,由编译器自动分配释放,存放函数的参数值,局部变量的值等,只有局部作用域,在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回(GC)垃圾回收机制(GC)原理:垃圾收集器会按照固定的时间间隔,周期性找出不再使用的变量,然后释放其占用的内存。不再使用的变量也就是生命周期结束的变量,是局部变量,局部变量只在函数的执行过程中存在,当函数运行结束,没有其他引用(闭包),那么该变量会被标记回收。全局变量的生命周期直至浏览器卸载页面才会结束,也就是说全局变量不会被当成垃圾回收。当一个局部变量存在引用(闭包),该变量也不会被当成垃圾回收,始终存在于内存中。

  闭包这种将变量始终存储,大家知道有什么好处么?可以仔细研究想想,再深剖会发现,闭包在性能优化方面优势很明显,对比下return,如图所示:

闭包与return对比

  如上代码,通过闭包,在外部对数据进行操作时候,红框内代码不会再一次执行,也就是f1里面劈里啪啦一顿猛如虎的操作之后获得的n,存储到内存中后,外部操作实际上是对存储在内存上的数据进行了操作。相比return,如果外部想获得内部的私有数据再操作,那内部的程序在外部每获取一次就需要跑一次,这无形中消耗着电脑的性能,所以我觉得,闭包的合理使用,是可以降低电脑性能的消耗起到一定的优化性能的作用。不合理的使用闭包会导致内存泄漏。

  好了,谢谢你这么帅,还能看完我的分享,希望对你有所帮助(辛辛苦苦写了那么多,兄dei,点个赞再走吧),送你一朵?。

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:我对封装的理解

下一篇:图片横向等高瀑布流,每行占满,限制行数 的实现