汇总14种JavaScript循环遍历的用法

839 阅读7分钟

前言:

不整理不知道,整理吓一跳,原来JS有这么多不同的循环方式的,包含冷门的几个我一共整理出来14种。下面将会通过尽可能简单的事例进行说明。

先直入主题看看分别是哪些循环方式:

1、for循环
2、while 循环
3、do...while循环
4、forEach循环
5、map()循环
6、for…in循环
7、for...of 循环
8、filter()过滤循环
9、some()循环
10、every()循环
11、Object.keys循环对象属性
12、Object.getOwnPropertyNames()循环对象的属性
13、reduce()循环
14、reduceRight()循环

1、for循环

简单介绍for 是最早出现的循环,也是最常用的一种循环机制,能够满足大部分的遍历。主要是依靠下标来获取数组内成员。

let arr = ['a', 'b', 'c'];
for (let i = 0; i < arr.length; i++) {
    console.log(i, arr[i])
}
// 0 'a'
// 1 'b'
// 2 'c'

注意:for 循环体中可以使用 break(跳出循环)和 continue(阻止当前轮循环继续往下执行,并且进入下一轮循环)

如下所示:找到想要的内容就用break停止循环

let arr = ['a', 'b', 'c'];
for (let i = 0; i < arr.length; i++) {
    if(arr[i]==='a'){
        console.log(i, arr[i])
        break
    }
}
// 0 'a'

如下所示:某种条件下使用continue可以跳过当前循环,但不影响后面的执行。

let arr = ['a', 'b', 'c'];
let s = []
for (let i = 0; i < arr.length; i++) {
    if(arr[i]==='a'){
        continue
    }
    s.push(arr[i])
}

console.log(s); // [b, c]

2、while 循环

简单介绍: While语句包括一个循环条件和一段代码块,只要判断到条件为真,就不断循环执行代码块,直到条件为假。

let i = 0; 
while (i < 10) { 
    console.log('当前为:'  i); 
    i = i + 1; 
}

3、do...while循环

简单介绍do...while循环与while循环非常类似,唯一的区别是先运行一次循环体,然后判断循环条件。

let i = 3;
do {
    console.log(i)
    i--;
}
while (i > 0)
// 3
// 2
// 1

4、forEach循环

简单介绍forEach方法将数组的所有成员依次传入参数函数,回调函数可以有三个参数。

  • 第一个参数:是当前元素的值
  • 第二个参数:是当前元素的索引
  • 第三个参数:是整个数组本身。

注意:不支持使用 break 或 continue 语句来中断循环,这意味着一旦开始,它会一直执行到数组的末尾。并且不返回任何值,它只是单纯地用于改变数组。

arr.forEach(function(item, index,arrs) {
    console.log(item, index, arrs);
    // 在这里做一些逻辑操作,可以改变当前arr数组
});

5、map()循环

简单介绍map() 方法也用于遍历数组,但它和 forEach() 的主要区别在于map创建了一个新的数组,该数组的结果是原始数组中的元素经过逻辑处理后的值。

注意return可以返回一个新数组,break会报错,不能跳出循环,这意味着一旦开始,它会一直执行到数组的末尾。

let arr = [1, 2, 3];
 
let nawArr = arr.map(function (n) { 
     return n + 1; 
}); 
console.log(nawArr); //返回新的数组 [2, 3, 4] 
 
console.log(arr);  //原数组不变 [1, 2, 3]

6、for…in循环

简单介绍for in 循环是 ES5 中新增的循环,循环遍历目标的所有可枚举的属性(包括原型上的),并且尽量只用来循环对象。

var textObj = {a: 1, b: 2, c: 3}; 
 
for (var i in textObj) { 
    console.log('键名:', i); 
    console.log('键值:', textObj[i]); 
} 
// 键名: a 
// 键值: 1 

// 键名: b 
// 键值: 2

注意:这里有一个坑需要注意,由于原循环到原型上的属性,那么继承的属性是可遍历的,这就会被for in循环遍历到。所以如果只想遍历到自身的属性,那么使用for in的时候应该结合使用hasOwnProperty方法,在循环内部判断一下某个属性是否为对象自身的属性。否则就可以产生遍历到不是自身对象属性的情况。

如下所示:加上hasOwnProperty后只能拿到自身属性

for (var i in textObj) { 
    if (textObj.hasOwnProperty(i)) {   
        console.log('键名:', i); 
        console.log('键值:', textObj[i]); 
      }
} 

7、for...of 循环

简单介绍for ofES6 中新增的循环遍历语句,通常用来遍历一个可迭代的对象(数组、集合、字符串等)

循环数组用法

let arr = [10,20,30]

for(let i of arr) {
    console.log(i);//10   20    30
}

循环字符串用法

let str = 'bba'

for(let i of str) {
    console.log(i); // b b a
}

循环Map()用法(经常与Map搭配使用)

const map = new Map([
  ["key1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"],
]);
 
for (const [key, value] of map) {
  console.log(key + " - " + value);
}
/*
key1 - value1
key2 - value2
key3 - value3
*/

8、filter()过滤循环

简单介绍: filter() 方法用于创建一个新的数组,新数组中的元素是通过过滤指定数组中符合条件的所有元素。参数与 forEach() 和 map() 相同,并且不会修改原数组。

let arr = [1, 2, 3, 4, 5, 6]

let nums = arr.filter(num => num % 2 === 0);

console.log(nums); // [2, 4, 6]

9、some()循环

简单介绍: some() 方法用于判断数组中是否有元素满足条件。它会遍历数组,直到找到一个元素符合条件返回 true,此时 some() 方法立即返回 true 并停止进一步的遍历。如果没有找到满足条件的元素,则返回 false,并且some() 不会改变原数组。

let arr = ['a', 'b']

let nums = arr.some(num => num === 'a');

console.log(nums); // true

10、every()循环

简单介绍: every() 方法用于判断数组中的是否所有元素满足条件。这个方法会对数组中的每个元素执行,如果所有元素都符合条件,则 every() 返回 true;只要有任意一个元素不符合指定条件,every() 就会立即停止遍历并返回 false,并且不修改原数组。

let arr = [1, 2, 3]

let nums = arr.every(num => num >3);

console.log(nums); // false

11、Object.keys循环对象属性

简单介绍: Object.keys() 方法用于获取一个对象所有可枚举自有属性的键名,并以数组形式返回。

注意:仅返回对象自身的属性,不包括原型链上的属性。

let obj = {a: 1, b: 2, c: 3}; 

console.log(Object.keys(obj)); // 输出:['a', 'b', 'c']

以下不可枚举的情况是无法获取到的

let objSymbols = {};

let sym = Symbol('test');

objSymbols[sym] = 'value';

console.log(Object.keys(objSymbols)); // 输出:[],因为Symbol是不可枚举的

12、Object.getOwnPropertyNames()循环对象的属性

简单介绍: Object.getOwnPropertyNames() 方法用于获取一个对象所有(包括不可枚举的)自有属性的名称,并返回一个包含这些属性名的数组。

注意:仅返回对象自身的属性,不包括原型链上的属性,并且与 Object.keys() 不同,getOwnPropertyNames() 会返回所有类型的属性名,包括不可枚举的属性。

let obj = {a: 1, [Symbol('b')]: 2, c: 3};

Object.defineProperty(obj, 'd', {value: 4, enumerable: false});

console.log(Object.getOwnPropertyNames(obj)); // 输出:['a', 'b', 'c', 'd']

13、reduce()循环

简单介绍: reduce() 方法是用于对数组中的所有元素执行一个累积操作(从左到右),将数组折叠成单个值。它接受一个回调函数,该函数在数组的每个元素上执行,结合当前元素和前一个元素的累积结果。

基本语法:接收两个参数,一个为回调函数,一个为初始赋值;
第一个参数的回调函数又接收四个参数,分别为(初始值或计算结束后的返回值当前元素当前元素的索引当前元素所属的数组对象

arr.reduce(function(prev, currentValue, currentIndex, arrs), initialValue)

简单例子:

[1, 2, 3, 4, 5].reduce(function (a, b) {
  console.log(a, b);
  return a + b;
}, 10)

//最后累加结果:25 因为初始值是10

14、reduceRight()循环

简单介绍: reduceRight() 方法与 reduce() 类似,也是对数组的所有元素执行累加操作(从右到左),但它从数组的末尾开始向前遍历数组,其它都是和reduce() 一样的。

小结:

感觉有好几个都比冷门的,可能很多人从来都没有用到过(包括我自己),但可以不用但我们得会啊,如果漏了那些方式欢迎大佬们指导添加。