什么是闭包,闭包的作用。

什么是闭包?

有二个函数,相互嵌套。内层函数引用了外层函数的变量。这就是闭包

        function fn(){
        	var num=1
        	function fn2(){
        		console.log(num)
        	}
        }

闭包形成的条件?

1. 内部函数使用了外函数的变量(还包括外部函数的参数)

      function fn(){
        	var num=1
        	function fn2(){
        		console.log(num)      //这个num引用了外部的num
        	}
        }


2. 外部函数返回了内部函数。

      function fn(){
        	var num=1
        	function fn2(){
        		console.log(num)      
        	}
                return fn2   //把函数fn2通过return返回出去
        }


              上面就是外层函数return返回内部函数

下面是更深入的补充:
-----------------------------------------------------------------------------------------
这里详细说明一下为什么要用return,我可不可以直接fn2()直接调用吗?
    

    return 返回出去的是这个fn2函数本身。因为函数是引用类型,引用的是函数的地址。每次的值都会被保存。


例如:我把fn2用return返回出去------这里是一个每次调用都会自加的计数器案例

                  function fn(){

        	        var num=0

        	        function fn2() {

                        num++

                        console.log(num)
        		    
        	        }

        	            return fn2
        	            
                    }

                var f=fn()          这里我们调用fn()函数,执行函数fn()函数体内的代码,
                                    返回的结果是function fn2(){}这个函数体,这个时候函数
                                    内部还没有被调用。我们在用f()进行调用。然后fn2内部的
                                    num就会引用了外层的num。



                f()         //每次调用都会加1



如果return返回的是函数本身,函数是引用类型的。每次引用的都是地址。那么每次都会在原有的基础上去想加。如果把return fn2换成 fn2()直接调用。那么每次调用完内部函数就会销毁。每次的结果都是0.
为什么我们把return返回出去就不会被释放销毁了呢?我们把return返回出去。然后用f去接收。这样f就会指向fn2这个函数。内存就不会被销毁释放。而在函数内部调用函数。内存调用完会被立即销毁释放掉。


3. 在函数外,有变量引用函数内

var f = fn();   //此处调用函数fn,执行的结果就是函数fn2
f();            //此处调用的是fn2这个函数,执行以后指向外层函数的变量

闭包的作用:

访问函数内部变量、保持函数环境中一直存在,不会被垃圾回收机制处理

闭包的优点:保护函数内变量的安全不会被修改。在内存中维持一个变量,可以做缓存。

闭包的缺点:因为使用闭包,可以使函数在执行完后不被销毁,保留在内存中,如果大量使用闭包就会造成内存泄露,内存消耗很大

注意点:频繁的使用闭包会造成内存泄露。记得在退出函数之前,将不使用的局部变量赋值为null;

闭包是指在一个函数内部定义另一个函数,并且这个内部函数引用了外部函数的作用域中的变量,当这个内部函数作为返回值被传递到其他地方调用的时候,依然能够访问原始外部函数作用域内的数据的一种现象。 简单来说,就是如果某个函数可以记住并获取它被创建时所在环境的状态信息(即使该状态已经不在当前执行栈里),那么就形成了所谓的“闭包”。 ### 具体例子 ```javascript function outerFunction() { let count = 0; // 定义于outerFunction内 return function innerFunction(){ console.log(++count); }; } const closureExample = outerFunction(); closureExample(); // 输出1 closureExample(); // 再次调用后输出2 ``` 在这个示例中可以看出尽管`innerFunction()`是在其所属的外部函数`outerFunction`之后才被执行,但是由于构成了闭包的关系所以仍然能正确地操作原来属于外层函数`outerFunction`局部变量`count`. --- ### 主要用途 1. 数据隐藏和封装 - 利用闭包我们可以把某些特定的数据只暴露给那些有权限访问它们的实体。例如我们经常看到的一些JavaScript库会采用立即执行匿名函数的方式来构建私有的命名空间。 ```javascript (function(globalVar){ var privateData="this is secret"; globalVar.publicMethod=function (){ alert(privateData); } })(window); publicMethod();//弹窗显示"this is secret" ``` 2. 创建工厂模式下的对象构造器 —— 可以为每个实例保留独立的一份成员属性副本而不互相干扰。 3. 迭代定时任务场景 – 确保每次循环产生的延迟效果不会相互影响 。比如下面这种情况如果不使用额外措施就会导致所有按钮点击都触发最后那个index对应的alert: ```html <button>Click me</button> <script> for(var i=0;i<5;i++){ document.querySelector('button').addEventListener('click',function (){setTimeout(()=>{alert(i)},i*1000)}); } </script> ``` 为了修复这个问题就可以引入let代替var声明计数器或者手动形成闭包解决此问题. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值