华为鸿蒙北向开发中的闭包问题

官方链接:<HarmonyOS第一课>ArkTS语法介绍-华为开发者学堂

问题介绍:

function f(): () => number {
  let count = 0;
  let g = (): number => { count++; return count; };
  return g;
}

let z = f();
z(); // 返回:1
z(); // 返回:2


闭包
闭包是由函数及声明该函数的环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。

在上例中,f函数返回了一个闭包,它捕获了count变量,每次调用z,count的值会被保留并递增。

介绍是这样,但是会有人看不懂,可以说服自己第一个会返回一,但是不知道为什么第二次count值保留,而不是重新let为0

解决:

让我们通过内存模型分析来彻底理解这个闭包行为:

function f(): () => number {
  let count = 0;          // 步骤1:在堆内存创建count变量
  let g = (): number => {  // 步骤2:创建函数对象g(携带作用域引用)
    count++; 
    return count;
  };
  return g;               // 步骤3:返回g时保留对count的引用
}
// 执行阶段
let z = f(); // 此时内存状态:
             // - 创建执行上下文A
             // - A.count = 0
             // - A.g = 函数(携带对A.count的引用)
             
z(); // 调用时:
     // 1. 通过g的作用域链找到A.count
     // 2. A.count → 1
     // 3. 保持对A.count的引用
z(); // 再次调用:
     // 修改的是同一个A.count → 2

关键原理表格

阶段内存变化变量状态
f() 被调用时创建新的执行上下文(包含count=0)生成新的闭包环境
g 函数创建时记录当前词法环境(包含对count的引用)形成闭包
f() 执行完成时执行上下文A不会销毁(因为g仍引用A.count)闭包维持A环境存活
第一次调用 z()通过闭包找到A.count → 0 → 自增为1A.count = 1
第二次调用 z()仍然访问同一个A.count → 1 → 自增为2A.count = 2
重新执行 let z2 = f()创建新的执行上下文B(新count=0)z和z2操作完全独立的count变量

理解误区澄清

误区:"每次调用z()都会重新初始化count" 真相:只有当f()被重新调用时才会创建新环境。z始终指向第一次f()调用产生的闭包环境。

通过调试工具验证

在Chrome DevTools中执行以下操作:

  1. 设置断点在count++
  2. 观察每次调用时闭包中的count值变化:
    Closure (f) // 首次调用后保持活跃
      count: 0 → 1 → 2
    

类比理解

把闭包想象成一个保险箱

  1. f() 每次调用会新建一个保险箱(新的执行上下文)
  2. 放入初始现金count=0
  3. 给你一把钥匙g(函数引用)
  4. 每次用钥匙操作(调用z())都是在操作同一个保险箱里的钱
    // 计数器工厂
    function createCounter(start = 0) {
      let count = start;
      return {
        increment: () => ++count,
        get: () => count
      };
    }
    const counter = createCounter(10);
    counter.increment(); // 11 ← 闭包维持count状态
    counter.increment(); // 12
    

经典应用场景

通过理解闭包机制,就能掌握JavaScript中状态保持的核心原理。这正是React Hooks(如useState)实现的基础原理之一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值