JavaScript基础——多种循环遍历

本文针对 javascript 和 es6 的循环方法做了如下整理工作:1)整理了和 for 相关的循环,如 for循环、for...in、for...of , 2)整理了仅用于数组中的较常见的循环方法,如 map、forEach、filter、reduce,欢迎讨论!

 

一、for 循环:索引遍历

二、for...in 循环:对象专用,只能索引遍历

三、for...of 循环:多种遍历

四、map():数组专用

五、forEach():数组专用

六、filter():数组专用

七、reduce():数组专用

八、对比总结


一、for 循环:索引遍历

var arr = [1, 2, 3];

for(let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

二、for...in 循环:对象专用,只能索引遍历

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

for(let i in obj) {
    console.log(i);  //键名
    console.log(obj[i]);  //键值
}

for...in 用来遍历一个对象的全部属性,1)它遍历的是对象所有可遍历的属性,会跳过不可遍历的; 2)不仅遍历对象自身的属性,还遍历继承的属性

如果只想遍历对象自身的属性,则应该结合使用hasOwnProperty方法

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

for(let i in obj) {
    if(obj.hasOwnProperty(i)){  //判断i是不是对象自身的属性
        console.log(i);  //键名
        console.log(obj[i]);  //键值
    }
}

最后,需要注意,不推荐使用 for...in 遍历数组,因为它还会遍历非数字键!

 

三、for...of 循环:多种遍历

for...of 是ES6中新增的遍历方法,我们需要先介绍一下 Iterator(遍历器)。Iterator是ES6为了可以处理不同的数据结构,而提出的一种统一的接口机制任何数据接口,只要部署了Iterator接口,就可以用 for...of 完成遍历操作

原生具备Iterator接口的数据结构如下:

  • 数组、字符串(for...of 在遍历数组时,它的遍历器接口只返回数字索引的属性。
  • Map、Set
  • 函数的arguments对象
  • DOM NodeList对象
  • Generator对象
var arr = [1, 2, 3];

for(let value of arr) {
    console.log(value);
}

for...of 默认是键值遍历,而ES6中提供的3个新方法 entries() 、keys() 、values() 专用于遍历数组,可以有多种方式。

var arr = ['a', 'b', 'c'];

for(let i of arr.keys()) {  //遍历键名
    console.log(i);  
} //0 1 2

for(let value of arr.values()) {  //遍历键值
    console.log(value); 
} //a b c

for(let [i, value] of arr.entries()) {  //遍历键值对
    console.log(i);
    console.log(value); 
} //0 'a'    1 'b'   2 'c'

 

四、map():数组专用

map( ) 将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回,不改变原数组。MDN中对map结构的描述已经很清楚了,这里简单的整理了一下。

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
    //callback:生成新数组元素的回调函数,使用三个参数
    //currentValue:必须,数组中正在处理的当前成员
    //index:可选,当前成员的位置
    //array:可选,数组本身
    //thisArg:可选,回调函数内部的this指向
}[, thisArg]);

示例:

var arr = [1, 2, 3];

var map_arr = arr.map(function (value) {
    return value + 1;
}); //[2, 3, 4]

arr; //[1, 2, 3]

注意,map方法不会跳过undefined和null,但会跳过空位。[1,  , 3]

五、forEach():数组专用

forEach() 与map() 相似,也不改变原数组,唯一的区别在于forEach只是操作数据,不会返回值,因此如果数组遍历的目的是为了得到返回值,就用map方法,否则只是为了在屏幕输出内容就使用forEach方法。结构如下:

arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);

//callback:生成新数组元素的回调函数,使用三个参数
//currentValue:必须,数组中正在处理的当前成员
//index:可选,当前成员的位置
//array:可选,数组本身
//thisArg:可选,回调函数内部的this指向

示例:

var arr = [1, 2, 3];

arr.forEach(function (value) {
    console.log(value + 1);
});

注意,forEach方法无法中途跳出循环,break和return都无效!如果希望符合某种条件就中断遍历,那么应该使用for循环!

forEach也会跳过数组的空位!

六、filter():数组专用

filter() 用于过滤数组成员,满足条件的成员组成一个新数组返回!不会改变原数组,与map相似。结构如下:

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

示例:

var arr = [1, 2, 3];

var filter_arr = arr.filter(function (value) {
    return value > 1;
});  //[2,3]

七、reduce():数组专用

reduce() 和reduceRight() 依次处理数组的每个成员,最终累计为一个值。

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]);

//accumulator:累积变量,默认为数组的第一个成员,或initialValue

//currentValue:当前变量,默认为数组的第2个成员

//index:可选,当前位置,如果提供了initialValue,则起始索引号为0,否则从索引1起始。

//initialValue:可选,reduce的第2个参数,作用是对累计变量设定初值,处理空数组时尤其有用!

说明,

1. 如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。

2. 对于空数组,指定reduce的初值更安全,否则可能报错!

详见 JS数组reduce()方法详解及高级技巧

八、对比总结

针对数组的遍历,可以使用for、for...of,优先使用for。

针对对象的属性遍历,使用for...in,注意需要结合hasOwnProperty判断是否为自身的属性。

针对数组的操作,

(1)map、forEach、filter方法的内部结构相同,都是回调函数和4个参数,但由于forEach不返回值,因此回调函数不需要return。

(2)map和forEach方法除了是否返回值,其余都相同。

(3)forEach不能中断循环,因此如果需要中途跳出循环时,建议使用for循环。

猜你喜欢

转载自blog.csdn.net/huaf_liu/article/details/115439155
今日推荐