闭包

一、什么是闭包?
  • 找一个作用域中可以访问另一个作用域的变量
    理解闭包的关键在于:外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。
二、如何产生一个闭包

就是在一个函数内部创建另一个函数
.通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。

//未发生闭包
function fn(){
var n=10;
return n;
}
fn();
//f发生闭包
function fn(){
                var n=10;
                return function(){
                    return n;
                }
            }
            var fn1=fn();
            console.log(fn1());

延迟函数的生命

在这里插入图片描述
在这里插入图片描述

二、点击事件使用闭包
  • 实例
    点击事件对应的索引不一样:两个时间不一样 for是加载就执行 但是点击是点击才执行但是for已经循环完了
    <script type="text/javascript">
        //1|给li注册点击事件
        var hereoes=document.querySelectorAll('li');
        for(var i=0;i<hereoes.length;i++){
            var li=hereoes[i];
            li.onclick=function(){
                    //2、dianjili的时候输出当前li对应的索引
            console.log(i);
            }
        }   
    </script>
  • 始终是4和预期不一样
  • 解决1存起来给每个li添加自己的检索属性
<script type="text/javascript">
        //1|给li注册点击事件
        var hereoes=document.querySelectorAll('li');
        for(var i=0;i<hereoes.length;i++){
            var li=hereoes[i];
            //记录索引
            li.index=i;
            li.onclick=function(){
                    //2、dianjili的时候输出当前li对应的索引
            console.log(this.index);
            }
        } 
    </script>
  • 使用闭包
<script type="text/javascript">
        //1|给li注册点击事件
        //使用闭包
        var hereoes=document.querySelectorAll('li');
        for(var i=0;i<hereoes.length;i++){
            var li=hereoes[i];
            //记录索引
            (function (i){
                li.onclick=function(){
                    //2、dianjili的时候输出当前li对应的索引
                console.log(i);
            }
            })(i);   
        } 
    </script>

闭包不会立即释放延展作用域

三、定时器应用闭包
    console.log('1');
    setTimeout(function(){
        console.log(2);
    },0);
    console.log(3);

    ;(function(){
        var a=0;
        setInterval(function(){
        console.log(a++);
    },1000)
        })();
    </script>

1
3
2

在这里插入图片描述

  • 先执行执行栈,先把执行栈执行完再执行任务队列
四、闭包缺陷

闭包的缺点就是常驻内存会增大内存使用量,并且使用不当很容易造成内存泄露。如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

五、面试题
function fun(n,o){
    console.log(o);
    return {
        fun:function(m){
            return fun(m,n);
        }
    };
}
//n=0 o=undefined
var a=fun(0); 
//undefined
a.fun(1);
//0
a.fun(2);
//0
a.fun(3);
//0
var b=fun(0).fun(1).fun(2).fun(3);//undefined  0 1 2
var c=fun(0).fun(1);//undefined 0
c.fun(2);//1
c.fun(3);//1
  • 面试2
var name='1';
var obj={
    name:'2',
    fn:function(){
        return function(){
            return this.name;
        };
    }
};
var fn=obj.fn();
console.log(fn());//1

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值