浅谈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)使用,把闭包当做它的公用方法,把内部变量当做它的私有属性,这时你需要做的是,加倍小心,不要随便改变函数的值,否则你会后悔的。

六、总结

对于闭包的活学活用,一直需要通过不断地项目经验的累积,才能每次都能得出更为深刻的认识,想要成为一名优秀的前端工程师,既要知其然,也要知其所以然,才能让自己变得更加优秀。

原文地址:https://www.cnblogs.com/bettermu/p/8450256.html