JavaScript中数组引用传递行为成因及forEach执行异常咨询
问题分析与解决方案
这确实和数组的引用特性直接相关,咱们一步步拆解你的问题:
1. JavaScript中数组的传递本质
首先要明确:在JavaScript里,数组属于引用类型,函数传递引用类型时,传递的是指向内存中对象的引用,而不是创建一个新的数组副本。所以你的array变量和arrayReference指向的是同一个数组对象,修改其中一个,另一个也会跟着变——这就是你觉得“像按引用传递”的原因,本质上是引用类型的共享特性。
2. 为什么forEach只执行一次?
咱们模拟一下代码的执行流程:
- 初始时
arrayReference是[1, 2],myFunction里的array和它指向同一个数组 - 调用
array.forEach(),开始迭代:- 第一次迭代:取索引0的元素
1,执行remove(elem.attr('id'))(这里假设elem的id对应数组值1) remove函数里用$.each遍历arrayReference,找到值为1的元素,调用splice(index, 1)把它删掉——此时原数组变成[2]- 这时候forEach的迭代器准备走到索引1,但现在数组的长度已经变成1了,索引1不存在,所以循环直接终止,不会执行第二次迭代
- 第一次迭代:取索引0的元素
这就是为什么remove功能只执行一次的核心原因:循环过程中修改了原数组的长度,导致迭代提前结束。而注释掉remove后,数组没被修改,forEach自然会完整遍历两个元素。
3. 解决方案:遍历数组的副本
如果你想在遍历的同时修改原数组,又不想影响循环的执行,可以遍历数组的副本,比如用slice()方法创建一个浅拷贝:
function myFunction() { var array = getArray(); // 遍历数组副本,原数组的修改不会影响循环 array.slice().forEach(function (elem) { remove(elem.attr('id')); }); }
这样forEach会遍历初始数组的完整副本,即使原数组被splice修改,也不会打断循环的执行。
内容的提问来源于stack exchange,提问作者Klyner
相关产品推荐
相关产品推荐

