JS 循环 OR 数组遍历

while

while(){
    //......
}

do-while

do{
    //......
}while(){
    //......
}

for

for(var i = 0; i < array.length; i++){
    //......
}

forEach

// currentValue 当前元素
// index            当前元素的索引值。
// arr          当前元素所属的数组对象。
// thisValue     传递给函数的值一般用 "this" 值。如果这个参数为空, "undefined" 会传递给 "this" 值
objArr.forEach(function(currentValue, index, arr){
    console.log(value);
}, thisValue);

// IE 8及更早版本不支持

// 用 forEach 遍历数组的话,不能中断循环(使用 break 或者 return)
// 如果要提前终止,必须把 forEach() 方法放在一个 try 块中,并能抛出一个异常。如果 forEach()调用的函数抛出 foreach.break 异常,循环会提前终止
function foreach(a, f, t){
    try {
        a.forEach(f,t)
    }catch(e){
        if(e === foreach.break)return;
        else throw e;
    }
}
foreach.break = new Error("StopIteration");

forEach 还有其他问题请参考:https://zhuanlan.zhihu.com/p/614624783?utm_id=0

for-in

// 所有浏览器都支持

for-in 语句用于遍历对象或者数组的属性(键名)

let es6 = {
    edition: 6,
    committee: "TC39",
    standard: "ECMA-262"
};      
for (let e in es6) {
    console.log(e); // edition committee standard
    console.log(es6[e]); // 6 TC39 ECMA-262
}


let objArr = [ 'a', 'b', 'c' ];
for(var index in objArr){
    console.log(index) // 0 1 2
    console.log(objArr[index]) // a b c
}


`for-in 循环实际是为循环 ”enumerable“ 对象而设计的`

**** 数组上不建议使用 for-in 循环 ****
以上代码会出现的问题:
1.index 值是字符串(String)类型,可能无意间进行字符串的计算 “2” + 1 = “21” 等,所以不能直接进行几何运算
2.循环不仅会遍历数组元素,还会遍历任意其他自定义添加的属性,如,objArr上 面包含自定义属性,objArr.name,那这次循环中也会出现此 name 属性
3.某些情况下,上述代码会以随机顺序循环数组

for-of

// currentValue  必须。当前元素的值
for(let currentValue of objArr){
    console.log(currentValue)
}
JavaScript6 里引入了一种新的循环方法,它就是 for-of 循环,它既比传统的 for 循环简洁,同时弥补了 forEach 和 for-in 循环的短板

如果循环普通对象,会报错 // TypeError: es6[Symbol.iterator] is not a function 或者 // Uncaught TypeError: es6 is not iterable
解决方法是,使用 Object.keys 方法将对象的键名生成一个数组,然后遍历这个数组
for (let key of Object.keys(someObject)) {
    console.log(key + ': ' + someObject[key]);
}

如果使用 for of 想要获取当前索引值
var arr = [ 'a', 'b', 'c' ];
for( let [ index, currentValue ] of new Map( arr.map( ( item, i ) => [ i, item ] ) ) ) {
    console.log(index, currentValue);
}
或者
for( let [ index, currentValue ] of arr.entries() ) {
    console.log(index, currentValue);
}

`for-of 可以使用 break、continue 、return 退出循环`

`for-of 主要遍历 可迭代对象(iterable)`

for-of 可以循环遍历很多东西
1、循环一个数组(Array)
2、循环一个字符串
3、循环一个类型化的数组(TypedArray)
4、循环一个 Map
5、循环一个 Set
6、循环一个 DOM collection(节点)
7、循环一个拥有 enumerable 属性的对象
8、循环一个生成器(generators)

map

// currentValue 必须。当前元素的值
// index    可选。当前元素的索引值
// arr  可选。当前元素属于的数组对象
// thisValue  对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。

array.map(function(currentValue, index, arr), thisValue)

// IE 8及更早版本不支持

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let newArr = arr.map(item => item * 2);
console.log(newArr) // [2, 4, 6, 8, 10, 12, 14, 16, 18]

map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改原始数组。

filter

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。

array.filter(function(currentValue, index, arr), thisValue)

// IE 8及更早版本不支持

var ages = [32, 33, 16, 40];
let newAges = ages.filter(function(currentValue){
    return currentValue >= 18;
})
console.log(newAges) // [32, 33, 40]


// 移除数组中所有的 ”false“ 类型元素
let b = a.filter(Boolean)
// 等同于
let b = a.filter(function(x) { return Boolean(x); })

find

array.find(function(currentValue, index, arr),thisValue)

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值
find() 方法为数组中的每个元素都调用一次函数执行

当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数
如果没有符合条件的元素返回 undefined

注意: find() 对于空数组,函数是不会执行的
注意: find() 并没有改变数组的原始值
注意: IE 11 及更早版本不支持 find() 方法

var ages = [3, 10, 18, 20];
function checkAdult(age) {
    return age >= 18;
}
function myFunction() {
    document.getElementById("demo").innerHTML = ages.find(checkAdult); // 18
}

findIndex

array.findIndex(function(currentValue, index, arr), thisValue)

findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置
findIndex() 方法为数组中的每个元素都调用一次函数执行

当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数
如果没有符合条件的元素返回 -1

注意: findIndex() 对于空数组,函数是不会执行的
注意: findIndex() 并没有改变数组的原始值
注意: IE 11 及更早版本不支持 findIndex() 方法

var ages = [3, 10, 18, 20];
function checkAdult(age) {
    return age >= 18;
}
function myFunction() {
    document.getElementById("demo").innerHTML = ages.findIndex(checkAdult); // 2
}

some、every

var resSome = array.some(function(currentValue, index, arr),thisValue)

// IE 8及更早版本不支持

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)
some() 方法会依次执行数组的每个元素
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测
如果没有满足条件的元素,则返回false
注意: some() 不会对空数组进行检测
注意: some() 不会改变原始数组


var resEvery = array.every(function(currentValue, index, arr), thisValue)

// IE 8及更早版本不支持

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)
every() 方法使用指定函数检测数组中的所有元素
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测
如果所有元素都满足条件,则返回 true
注意: every() 不会对空数组进行检测
注意: every() 不会改变原始数组

reduce、reduceRight

// total              必需。initialValue 的初始值, 或者计算结束后的返回值
// currentValue       必需。当前元素
// currentIndex       可选。当前元素的索引
// arr                可选。当前元素所属的数组对象
// initialValue       可选。传递给函数的初始值

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

// IE 8及更早版本不支持

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
reduce() 可以作为一个高阶函数,用于函数的 compose
注意: reduce() 对于空数组是不会执行回调函数的

let arr = [1, 2, 3];
let ad = arr.reduce(function(i, j){
    return i + j;
})



reduceRight 和 reduce 相反,是从右到左



var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
})
console.log(arr, sum);

上面的例子索引是从 1 开始的,第一次的 prev 的值是数组的第一个值。数组长度是 4,但是 reduce 函数循环 3次


var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
}, 0);
console.log(arr, sum);

如果没有提供 initialValue,reduce 会从索引 1 的地方开始执行 callback 方法,跳过第一个索引
如果提供 initialValue,reduce 会从索引 0 的地方开始,reduce 函数循环 4次


求和
var  arr = [1, 2, 3, 4];
var sum = arr.reduce((x, y) => x + y)
console.log(sum); // 10

求乘积
var  arr = [1, 2, 3, 4];
var mul = arr.reduce((x, y) => x * y)
console.log(mul); // 24


计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre, cur) => {
    if(cur in pre){
        pre[cur]++
    }else{
        pre[cur] = 1;
    }
    return pre
}, {});
console.log(nameNum); // { Alice: 2, Bob: 1, Tiff: 1, Bruce: 1 }


数组去重
let arr = [1, 2, 3, 4, 4, 1];
let newArr = arr.reduce((pre, cur) => {
    if(!pre.includes(cur)){
        return pre.concat(cur);
    }else{
        return pre;
    }
}, []);
console.log(newArr); // [1, 2, 3, 4]


将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre, cur) => {
    return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]


将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4, [5, 6, 7]]]
const newArr = function(arr){
    return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur), [])
}
console.log(newArr(arr)); // [0, 1, 2, 3, 4, 5, 6, 7]


对象里的属性求和
var result = [
    {
        subject: 'math',
        score: 10
    },
    {
        subject: 'chinese',
        score: 20
    },
    {
        subject: 'english',
        score: 30
    }
];

var sum = result.reduce(function(prev, cur) {
    return cur.score + prev;
}, 0);
console.log(sum) // 60


数组转对象
const list = [
    { name: 'yzw', area: 'gz', age: 27, sex: '男' },
    { name: 'tyj', area: 'sz', age: 24, sex: '女' }
];
const map = list.reduce((prev, cur) => {
    const { name, ...rest } = cur;
    prev[name] = rest;
    return prev;
}, {});
console.log(map);
// {
//     tyj: { area: 'sz', age: 24, sex: '女' }
//     yzw: { area: 'gz', age: 27, sex: '男' }
// }

Object.keys() 遍历对象的属性名,返回一个数组

let obj = { foo: 'bar', baz: 42 };
Object.keys(obj) // ["foo", "baz"]

Object.values() 遍历对象的属性值,返回一个数组

let obj = { foo: 'bar', baz: 42 };
Object.values(obj) // ["bar", 42]

Object.entries() 遍历对象的属性的键值对数组,返回一个数组

let obj = { foo: 'bar', baz: 42 };
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]

Object.fromEntries() 是 Object.entries() 的逆操作,将一个键值对数组转为对象

Object.fromEntries([
    ['foo', 'bar'],
    ['baz', 42]
])
// { foo: "bar", baz: 42 }

Object.getOwnPropertyNames() 遍历对象的属性

Object.getOwnPropertyKeys() 遍历对象的属性值

你可能感兴趣的:(JS 循环 OR 数组遍历)