循环体对数组的增减是否会影响for循环,增加的元素是否会被循环?for与for in详解
先来看第一个for循环
for (let i=0;i<arr.length;i++) {
if (arr[i]==2) {
arr.push('6')
}
console.log(arr[i])
}//输出1,2,3,4,5,6 即添加的元素使arr变长,arr.length会重新计算
最普通的for循环,输出了在循环体中加入的元素,说明for循环中的arr.length的长度在不断变化 ,在循环过程中数组长度发生了变化,for循环的arr.length也会跟着更新
第二个数组循环for in
for(let i in arr){
if (arr[i]==2) {
arr.push('6')
}
console.log(arr[i])
}//输出1,2,3,4,5 arr的长度不会被重新计算
for in 遍历数组,数组长度增加,但并没有更新到for中的arr,arr的长度没有被重新计算,我猜测for in作为专属数组遍历的语句,可能在for in执行的那一瞬间就将arr缓存起来了,后续更新arr,arr会变化,但已执行的for in中的arr不会被更新
for循环和for in减少数组元素的测试
let arr = [1,2,3,4,5]
for (let i=0;i<arr.length;i++) {
if (arr[i]==2) {
arr.splice(1,1)
}
console.log(arr[i],'0')
}//输出1,3,4,5 即减少的元素使arr变短,arr.length会重新计算
减少的元素使arr变短,,arr.length实时更新
如果将上述的console.log(arr[i])放在if的前面,则会输出1,2,4,5,这是因为删除元素并不会影响i,i依旧是自增的,当满足if语句后删除下标为1的元素后,i自增,下次循环会i=2,即第三个元素,也就是4(2已被删除)
for(let i in arr){
if (arr[i]==2) {
arr.splice(1,1)
// arr.push('6')
}
console.log(arr[i])
}//输出1,3,4,5 arr的长度也会重新更新
输出和for循环一致,减少数组元素for in也一样会重新计算长度
结论:
for只是循环结构,循环体中数组的长度改变,for循环的次数也会跟着改变,无论增减都是一样的;
for in是数组专属的遍历结构,循环体增加数组的长度并不会影响遍历,但减少数组元素则会更新for in遍历次数,我猜测for in在执行前就已经将数组缓存起来了,增加数组并不会影响for in,如果减少数组元素依旧使用缓存,那肯定会报错,遍历了一个已经删除的数组元素,所以开发者将这两个情况做了区分,数组增加使用缓存,数组减少则更新for in数组
我认为应该尽量不在循环体中使用数组减少的操作,那样会让逻辑变的复杂,出现很多不可预见的错误,当需要减少数组元素的时候可以声明一个空数组,遍历旧数组,判断符合条件,加入到新数组中,最后返回新数组即可,代码如下
// 场景 去掉arr中的3(下标为2)
let arr = [1,2,3,4,5]//老数组
arr = fangfa(arr)
console.log(arr)//输出 1,2,4,5
function fangfa(arr){
let newarr = []
for(let i in arr){
if (arr[i]!=3) {
newarr.push(arr[i])
}
}
return newarr
}
欢迎交流