js闭包相关题

一.闭包的概念以及特性

  1. 概念:在函数的内部定义一个函数,使其能够读取其他函数的局部变量
  2. 作用:读取其他函数的内部变量,是将函数的内部和外部连接起来的桥梁,可以用来实现模块化
  3. 形成条件:函数的嵌套
  4. 特性:
    • 封闭性:外界无法访问闭包内的数据,除非闭包向外界主动提供接口
    • 持久性:一般函数在被系统调用之后都会被注销掉,对于闭包而言,当外部函数被调用之后不会被立即注销
  5. 优缺点:
    • 优点:延长外部函数局部变量的生命周期
    • 缺点:过多的占用内存,造成内存泄漏
  6. 注意:所有闭包中的this都是指向window
  7. 语法:
   var fun1 = () => {
       var num = 999;
       var fun2 = () => {
           return num
       }
       return fun2;
   }
   fun1()();    // 999

二.有关闭包的常见面试题

  1. 打印计时器的值
for (var i = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  }, 0)
}
// 5 5 5 5 5

// 解决办法:
// 1. 闭包
for ( var i = 0 ; i < 5 ; ++i ) {
  (function(cacheI){
      setTimeout(function(){
          console.log(cacheI);
      },0)
  })(i)
}  ;
// 0 1 2 3 4

// 2. 用let声明变量,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量。而每个setTimeout引用的都是不同的变量实例,所以输出的时我们期望的值,也就是循环过程中每个迭代变量的值:
for (let = 0; i < 5; i++) {
  setTimeout(function () {
    console.log(i);
  }, 0)
}
// 0 1 2 3 4
  1. 函数返回值
function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);
// 问:三行的输出分别是什么?
// undefined,0,0,0
// undefined,0,1,2
// undefined,0,1,1

第一行:
可以得知,第一个fun(0)是在调用第一层fun函数。
第二个fun(1)是在调用前一个fun的返回值的fun函数
第后面几个fun(1),fun(2),fun(3),函数都是在调用第二层fun函数。

在第一次调用fun(0)时,o为undefined第二次调用fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0并在内部调用第一层fun函数fun(1,0);所以o为0第三次调用fun(2)时m为2,但依然是调用a.fun,所以还是闭包了第一次调用时的n,
所以内部调用第一层的fun(2,0);所以o为0;
第四次同理;
即:最终答案为undefined,0,0,0

第二行:
先从fun(0)开始看,肯定是调用的第一层fun函数;
而他的返回值是一个对象,所以第二个fun(1)调用的是第二层fun函数,后面几个也是调用的第二层fun函数。

在第一次调用第一层fun(0)时,o为undefined;
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时当前的fun函数不是第一次执行的返回对象,而是第二次执行的返回对象。
而在第二次执行第一层fun函数时时(1,0)所以n=1,o=0,返回时闭包了第二次的n,遂在第三次调用第三层
fun函数时m=2,n=1,即调用第一层fun函数fun(2,1),所以o为1;
第四次调用 .fun(3)时m为3,闭包了第三次调用的n,同理,最终调用第一层fun函数为fun(3,2);
所以o为2;
即最终答案:undefined,0,1,2

第三行:
fun(0)为执行第一层fun函数,
.fun(1)执行的是fun(0)返回的第二层fun函数,这里语句结束,
遂c存放的是fun(1)的返回值,而不是fun(0)的返回值,
所以c中闭包的也是fun(1)第二次执行的n的值。
c.fun(2)执行的是fun(1)返回的第二层fun函数,
c.fun(3)执行的也是fun(1)返回的第二层fun函数。

在第一次调用第一层fun(0)时,o为undefined; 
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,
也就是第一次调用的n=0,即m=1,n=0,并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时fun闭包的是第二次调用的n=1,即m=2,n=1并在内部调用第一层fun函数fun(2,1);所以o为1;
第四次.fun(3)时同理,但依然是调用的第二次的返回值,遂最终调用第一层fun函数fun(3,1),
所以o还为1
即最终答案:undefined,0,1,1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值