详细告诉你,什么叫闭包

本文深入探讨了JavaScript中的闭包概念,解释了它如何工作以及如何影响内存释放机制。通过学习,读者将更好地理解闭包在JavaScript程序中的作用和内存管理的重要性。
摘要由CSDN通过智能技术生成

闭包、内存释放机制

 let x = 5;
function fn(x) {
   
  return function(y) {
   
    console.log(y + (++x));
  }
}
let f = fn(6);// x = 6 执行fn函数所形成的的执行上下文不销毁,因为它里面创建的私有变量被外界的f占用了
f(7); // y=7; y+(++x) => 7+7=14 
fn(8)(9); // => x=8, y=9 y+(++x) =>9+9=18
f(10); // y=10, x=7  y+(++x) => 10+8=18
console.log(x); // 5 
/* 
 * 解析:本来画图更容易理解的,但是我这里不好画图,大家将就看哈
 全局作用域 EC(G)
    变量提升:
      fn = AF0  [[scope]]: EC(G)(函数是引用型,创建了堆内存,引用的是堆内存的地址)
    代码执行:
      x = 5;

      f = fn(6);
      fn(6)执行:形成一个新的执行上下文 EC(f1)
        初始化作用域链:
          [[scope-chain]] = <EC(f1), EC(G)>
        形参赋值:
          x = 6;
          执行完f(7)之后 x = 7
          执行完f(10)之后 x = 8
        代码执行:
          return function(y){...} 
          等价于返回一个堆内存地址,return AF1
        这个执行上下文中有私有变量AF1被外界f占用,所以不出栈销毁
      f = fn(6) === f=AF1
      
      f(7)执行:等价于AF1(7)执行 => 形成一个新的执行上下文 EC(f2)
        初始化作用域链:
          [[scope-chain]]: <EC(f2), EC(f1)>
        形参赋值:
          y = 7;
        代码执行:
          console.log(y+(++x)); y是私有的,值为7,x不是私有的,沿着作用域链查找,在EC(f1)中有x=6, ++x => x=7
          y+(++x) =>7+7 = 14
        这个执行上下文没有私有变量被外界引用,所以出栈销毁

      fn(8)(9); 分两步:先执行fn(8),再把其返回的结果执行并传参9
        fn(8)执行:形成一个新的执行上下文 EC(f3)
          初始化作用域链:
            [[scope-chain]] = <EC(f3), ED(G)>
            形参赋值:
              x = 8;
            代码执行:
              return function(y){...} [[scope]]: EC(f1)
              => return AF2  这里的解释跟fn(6)执行逻辑一样
          这个执行上下文中有私有变量要在全局接着执行,所以暂时不出栈销毁
        AF2(9)执行:形成一个新的执行上下文 EC(f4)
          初始化作用域链:
            [[scope-chain]] = <EC(f4), EC(f3)>
          形参赋值:
            y = 9;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值