js学习笔记之闭包

学习来源:https://www.zhihu.com/people/wang-wang-69-90-11/answers


首先清楚一点,在作用域篇有详细讲。

作用域链的第一个对象:引用本函数的参数和局部变量

作用域链的第二个对象:引用外层函数的参数和局部变量

.....
作用域链的最后一个对象:引用的全局的执行环境对象,也就是window对象


闭包:

闭包简单的说就是一个函数能访问外部函数的变量,这就是闭包,比如说:


function a(x){
      var tem=3;
      function b(y){
          console.log(x+y+(++tem));
     }
}

a函数中的b函数就是闭包了,b函数可以使用a函数的局部变量,参数。


最典型的闭包应该是下面这样,将定义在函数中的函数作为返回值:

function a(x){
      var tem=3;
      function b(y){
          console.log(x+y+(++tem));
     }
return b;

}

a(2)(3);


或是作为参数被传递
function a(){
    var x= 2;
    function b(){
        console.log(x);   //2
    }
    foo(b);
}
function foo(fn){
    fn();
}


闭包的另一种作用是隔离作用域,请看下面这段代码
for(var i=0;i<2;i++){
      setTimeout(function(){
              console.log(i);
        },0);

}

上面这段代码的执行结果是2,2而不是0,1,因为等for循环出来后,执行setTimeout中的函数时,i的值已经变成了2,这就是没有隔离作用域所造成的。

在循环的过程中,并没有把函数的返回值赋值给数组元素,而仅仅是把函数赋值给了数组元素。这就使得在调用匿名函数时,通过作用域找到的执行环境中储存的变量的值已经不是循环时的瞬时索引值,而是循环执行完毕之后的索引值。



由此,可以利用IIFE传参(立即执行函数:在定义函数之后,立即调用该函数)和闭包来创建多个执行环境来保存循环时各个状态的索引值。因为函数传参是按值传递的,不同参数的函数被调用时,会创建不同的执行环境
for(var i=0;i<2;i++){
      (function(i){
             setTimeout(function(){
             console.log(i);
              },0)
      })(i);

}

这样就会输出0,1,我们的立即执行函数创建了一个作用域,隔离了外界的作用域。


只要将内部函数传递到所在的作用域以外,它都会持有对原始作用域的引用,无论在何处执行这个函数都会使用闭包

严格来说,闭包需要满足三个条件:【1】访问所在作用域;【2】函数嵌套(访问父级作用域);【3】在所在作用域外被调用(作为返回值,作为参数)

闭包的缺点是因为内部闭包函数可以访问外部函数的变量,所以外部函数的变量不能被释放,如果闭包嵌套过多,会导致内存占用大,要合理使用闭包。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值