JS中forEach方法是否会创建数组副本?两种代码现象解析
关于JavaScript中forEach遍历机制的解释
首先明确:forEach从来不会创建数组副本,你的两个例子都可以通过它的底层遍历规则来解释。
第一个例子:为什么没有无限循环?
var li = [""] li.forEach(() => { li.push(""); });
调用forEach的瞬间,JS会先获取当前数组的length值(这里初始是1),之后的遍历过程中,不管你怎么修改数组的长度(比如push新增元素),forEach只会遍历到初始length对应的索引范围(也就是只执行1次回调)。新增的元素不会被纳入本次遍历的范围,所以自然不会无限循环。
第二个例子:为什么输出是「1 2 3 AA 5」?
var li2 = [1,2,3,4,5] li2.forEach((el) => { li2[3] = "AA"; console.log(el) });
forEach是按索引顺序遍历原数组的元素,每次回调里的el是当前索引对应的原数组实时值:
- 遍历索引0:取到原数组的1,输出1
- 遍历索引1:取到原数组的2,输出2
- 遍历索引2:取到原数组的3,输出3
- 遍历索引3:此时回调已经把原数组索引3的元素改成了「AA」,所以取到的就是修改后的「AA」,输出AA
- 遍历索引4:取到原数组的5,输出5
这里的关键是:forEach不会提前缓存所有元素的值,只是按初始确定的索引范围,逐个去原数组里取当前值。修改已有索引的元素会实时反映到回调中,但新增元素不会触发额外的遍历。
内容的提问来源于stack exchange,提问作者Manthe fraiche
相关产品推荐
相关产品推荐

