JS中push方法未直接操作chunked数组却更新其内容的原理是什么
核心原理说明
这个现象的本质是JavaScript中数组属于引用类型,赋值时传递的是内存地址引用而非值副本。你觉得没有直接修改chunked数组是误区,代码里的操作其实一直都在隐式或显式修改chunked:
具体执行逻辑拆解
我们逐步骤看chunk([1, 2, 3, 4, 5, 6, 7], 3)的运行过程:
- 初始化阶段:
chunked是空数组[] - 遍历第一个元素
1:chunked.length -1 = -1,chunked[-1]取值为undefined,触发if判断条件- 执行
chunked.push([element]),显式把新数组[1]推入chunked,此时chunked = [[1]]
- 遍历第二个元素
2:last = chunked[0],这里拿到的不是[1]的副本,是和chunked[0]指向同一块内存地址的引用- 此时
last.length = 1 < 3,触发else分支执行last.push(2) - 因为
last和chunked[0]指向同一个数组,修改last等价于直接修改chunked[0],执行后chunked = [[1,2]]
- 遍历第三个元素
3:- 和第二步逻辑一致,执行
last.push(3)后,chunked = [[1,2,3]]
- 和第二步逻辑一致,执行
- 遍历第四个元素
4:- 此时
last = chunked[0],last.length = 3刚好等于分块大小,触发if分支 - 显式执行
chunked.push([4]),新增分块,此时chunked = [[1,2,3], [4]]
- 此时
- 后续元素5、6会被推入第二个分块,将其填充为
[4,5,6];遍历到元素7时第二个分块已满,再次触发if分支推入新分块[7],最终得到你看到的结果。
误区澄清
你提到没有看到chunked.push(last)这类操作,是因为last本身就是chunked的内部元素,不需要再重复推入。每次新开分块时的chunked.push([element])已经完成了分块数组的挂载,后续对last的修改都是直接修改已挂载在chunked里的子数组内容。
内容的提问来源于stack exchange,提问作者Zachary Godwin
相关产品推荐
相关产品推荐

