浅谈JS中的闭包
今天 大年初一,祝各位小伙伴们狗年旺旺啊,闲来也没事,只能钻研一下自己的分内之事,也就是作为一个前端码农的身份,得时刻保持学习的态度,温故而知新,每天都给自己一个小目标去完成,日积月累,所想达到的状态,都会有所见长。
JS中的闭包,想必,做web开发的程序猿们都有一定的认识吧,不仅仅是js里有这种特性,而且弱语言类型的譬如python里也是有闭包这么一个强大的特性的,对于老司机们来说,闭包可真的是一个很好的东西,但是对于新入门的菜鸟们来说,闭包却是一个难以搞得清楚的特性,很多情况下,会用,但是却不能够深刻理解其中的含义,有些时候,出现问题了,也无法立刻找出问题的所在。下面我们来聊一聊js中的闭包相关的知识。
一、什么是闭包?
当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。
简单的来说,所谓的闭包就是一个具有封闭的对外不公开的,包裹结构或空间。
二、为什么函数可以构成闭包?
闭包就是一个具有封闭与包裹功能的结构,是为了实现具有私有访问空间的函数的。函数可以构成闭包。函数内部定义的数据函数外部无法访问,即函数具有封闭性;函数可以封装代码即具有包裹性,所以函数可以构成闭包
三、闭包有什么用(特性)
闭包的作用,就是保存自己私有的变量,通过提供的接口(方法)给外部使用,但外部不能直接访问该变量。
当我们需要在模块中定义一些变量,并希望这些变量一直保存在内存中但又不会“污染”全局的变量时,就可以用闭包来定义这个模块。
闭包的缺点:闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
函数套函数就是闭包吗?:不是!,当一个内部函数被其外部函数之外的变量引用时,才会形成了一个闭包。
四、闭包的基本模型
1、对象模式
函数内部定义个一个对象,对象中绑定多个函数(方法),返回对象,利用对象的方法访问函数内的数据
function createPerson() { var __name__ = ""; return { getName: function () { return __name__; }, setName: function( value ) { // 如果不姓张就报错 if ( value.charAt(0) === '张' ) { __name__ = value; } else { throw new Error( '姓氏不对,不能取名' ); } } } } var p = createPerson(); p.set_Name( '张三丰' ); console.log( p.get_Name() ); p.set_Name( '张王富贵' ); console.log( p.get_Name() );
2、函数模式
函数内部定义一个新函数,返回新函数,用新函数获得函数内的数据
function foo() { var num = Math.random(); function func() { return mun; } return func; } var f = foo(); // f 可以直接访问这个 num var res1 = f(); var res2 = f();
3、沙箱模式
沙箱模式就是一个自调用函数,代码写到函数中一样会执行,但是不会与外界有任何的影响,比如jQuery
(function () { var jQuery = function () { // 所有的算法 } // .... // .... jQuery.each = function () {} window.jQuery = window.$ = jQuery; })(); $.each( ... )
五、闭包的缺点
1、由于闭包会使得函数中的变量都保存在内存中,一方面会使内存消耗大,另一方面在ie下导致内存泄露,解决办法,在退出函数时,将不使用的局部变量全部删除(null掉吧)
2、闭包会在父级外部,改变父函数内部内部变量的值;所以,如果你把父函数当作对象(object)使用,把闭包当做它的公用方法,把内部变量当做它的私有属性,这时你需要做的是,加倍小心,不要随便改变函数的值,否则你会后悔的。
六、总结
对于闭包的活学活用,一直需要通过不断地项目经验的累积,才能每次都能得出更为深刻的认识,想要成为一名优秀的前端工程师,既要知其然,也要知其所以然,才能让自己变得更加优秀。