You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请结合map方法签名与闭包,分步解释这段JS代码的运行原理

拆解这段带闭包的map累加代码运行逻辑

首先明确map方法的签名:

array.map(function(currentValue, index, arr), thisValue)

map会遍历数组的每一个元素,依次调用传入的回调函数,每次调用时会自动传入三个参数:当前遍历到的元素currentValue、元素的索引index、原数组arr,最终返回一个由所有回调返回值组成的新数组。

先看懂代码的写法

你给出的代码里,map的参数是一个逗号表达式:(acc = 0 , num => acc += num)。逗号运算符的规则是依次执行所有操作数,返回最后一个操作数的值,所以这里实际发生的是:

  1. 先执行acc = 0,给变量acc赋值为0;
  2. 把后面的箭头函数num => acc += num作为回调函数传给map。

而这个箭头函数不会创建自己的词法环境,它会沿用定义时所在的上下文,所以acc会被所有回调调用共享,这就是闭包的作用——函数能访问并保留定义时环境里的变量。

分步可视化运行过程

初始化:

  • 变量acc被赋值为0;
  • map拿到的回调函数是num => acc += num。

开始遍历数组[1,2,3,4,5]:

  1. 第一次遍历(元素1):

    • 回调接收currentValue为1;
    • 执行acc += 1 → 0 + 1 = 1;
    • acc更新为1;
    • 回调返回1,新数组第一个元素是1。
  2. 第二次遍历(元素2):

    • 回调接收currentValue为2;
    • 执行acc += 2 → 1 + 2 = 3;
    • acc更新为3;
    • 回调返回3,新数组第二个元素是3。
  3. 第三次遍历(元素3):

    • 回调接收currentValue为3;
    • 执行acc += 3 → 3 + 3 = 6;
    • acc更新为6;
    • 回调返回6,新数组第三个元素是6。
  4. 第四次遍历(元素4):

    • 回调接收currentValue为4;
    • 执行acc += 4 → 6 + 4 = 10;
    • acc更新为10;
    • 回调返回10,新数组第四个元素是10。
  5. 第五次遍历(元素5):

    • 回调接收currentValue为5;
    • 执行acc += 5 → 10 + 5 = 15;
    • acc更新为15;
    • 回调返回15,新数组第五个元素是15。

最终map返回新数组[1,3,6,10,15],被console.log输出。

关于闭包的补充

这里的acc是闭包变量,意味着只要这个回调函数还能被访问到,acc的值就会一直保留。比如后续再用这个回调做map:

const cb = (acc = 0, num => acc += num);
console.log([1,2].map(cb)); // 输出 [1,3]
console.log([3].map(cb)); // 输出 [6](因为acc已经是3,加3变成6)

内容的提问来源于stack exchange,提问作者iamworldian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:15:36