开发中经常会遍历数组,也会有需要中断遍历的场景,在诸多遍历数组的方法中能否按照我们所想的那样中断遍历呢?
先上结论,再解释原因
let tempArr = ['a', 'b', 'c' , 'd'];
console.log(loopFn(tempArr));
/**
* forEach
*/
function loopFn(arr) {
arr.forEach((item, index) => {
if(index === 2) {
// break; // 报错:跳转目标不能跨越函数边界。
// continue; // 报错:跳转目标不能跨越函数边界。
return; // a b c d
}
console.log(item);
});
}
/**
* map
*/
function loopFn5(arr) {
const temp = arr.map((item, index) => {
if(index === 2) {
// return; // a b d | [ 'a', 'b', undefined, 'd' ]
// break; // 跳转目标不能跨越函数边界。
// continue; // 跳转目标不能跨越函数边界。
}
console.log(item); // a b d
return item;
})
console.log(temp); // [ 'a', 'b', undefined, 'd' ]
}
/**
* for 循环
*/
function loopFn2(arr) {
for (let index = 0; index < arr.length; index++) {
const element = arr[index];
if(index === 2) {
// continue; // a b d
// break; // a b
return; // a b
}
console.log(element);
}
}
/**
* for of
*/
function loopFn3(arr) {
for (const element of arr) {
if(element === 'c') {
// continue; // a b d
// break; // a b
return; // a b
}
console.log(element);
}
}
/**
* for in
*/
function loopFn4(arr) {
for (const iterator in arr) {
if(iterator === 2) {
// continue; // a b c d
// break; // a b c d
return; // a b c d
}
console.log(arr[iterator]);
}
}
/**
* while
*/
function loopFn6(arr) {
let i = -1;
while(i < arr.length) {
i++;
if(i === 2) {
// break; // a b
return; // a b
// continue; // a b d
}
console.log(arr[i]);
}
}
- 在数组的 forEach 和 map 方法中尝试使用 break 或 continue 跳出循环都会报错,这是因为 break 和 continue 都是用来跳出循环的,而 forEach 和 map 的第一个参数都是回调函数,在回调函数中使用 break 或 continue当然会报错。
- 在 forEach 中使用 return 也不会影响循环结果,这是因为在回调函数中使用 return, 只是将结果返回到上级函数,也就是这个 forEach 循环中,并没有结束 forEach 循环,所以使用 return 也是无效的;至于在 map 中使用 return 就不用过多解释了~ 可读一下 MDN。
- for 和 for of 都是用来遍历可迭代对象的(Array Set Map String arguments TypedArray),因此使用 continue、break 都能正常跳出循环,使用 return 也能正常将改方法的结果返回出去,使用 while 循环遍历数组效果和上面也一样。
- for in 用来以任意顺序迭代一个对象上除 Symbol 以外的可枚举属性,包括继承的可枚举属性,不推荐也不应该用在关注顺序的数组上面
总结:这个问题归根结底是要明白
return continue break的作用
return 语句终止函数的执行,并返回一个指定的值给函数调用者
continue 声明终止当前循环或标记循环的当前迭代中的语句执行,并在下一次迭代时继续执行循环。
break 语句中止当前循环,switch语句或label 语句,并把程序控制流转到紧接着被中止语句后面的语句。