JS几种数组遍历方式,高阶方法
一、forEach()
遍历数组,无返回值。理论上该方法没有返回值,仅仅是遍历数组中的每一项,不对原数组进行修改;但是可以通过数组的索引来修改原来的数组
方法中传入的 匿名回调函数中的this指向window
arr.forEach(function(value, index, array){
// arr中有几项,该匿名回调函数就需要执行几次
// value —— 数组中的当前项
// index —— 当前项的索引
// array —— 原始数组
})
例子:
var arr = [1,2,3,4,5]
var res = arr.forEach(function(item, index, arr){
arr[index] = item*2
})
console.log(res) //undefined
conosle.log(arr) //[2,4,6,8,10],通过数组索引改变了原数组
二、map()
遍历数组,有返回值。map的回调函数中支持return返回值,即把原数组克隆一份,把克隆的数组中对应项进行修改
方法中传入的 匿名回调函数中的this指向window
arr.map(function(value, index, array){
// arr中有几项,该匿名回调函数就需要执行几次
// value —— 数组中的当前项
// index —— 当前项的索引
// array —— 原始数组
return xxx
})
var ary = [1,2,3,4,5];
var res = ary.map(function (item,index,input) {
return item*10;
})
console.log(res);//-->[1,2,3,4,5]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[10,20,30,40,50]; 原数组并未发生变化
三、every()
遍历数组,判断数组中的每一项元素是否都满足条件,返回一个布尔值
arr.every(function(value, index, array){
// arr中有几项,该匿名回调函数就需要执行几次
// value —— 数组中的当前项
// index —— 当前项的索引
// array —— 原始数组
return xxx
})
//例子:判断arr中的元素是否都为正数
var arr = [1,-2,3,4,-5]
var isEvery = arr.every(function(item, index, array){
return item > 0
})
console.log(isEvery) // false
四、some()
遍历数组,判断数组中的是否存在满足条件的元素,返回一个布尔值
arr.some(function(value, index, array){
// arr中有几项,该匿名回调函数就需要执行几次
// value —— 数组中的当前项
// index —— 当前项的索引
// array —— 原始数组
return xxx
})
//例子:判断数组arr中是否存在负数
var arr = [1,-2,3,4,-5]
var isSome = arr.some(function(item,index,array){
return item < 0;
});
console.log(isSome); // true
五、filter()
遍历数组,筛选数组中满足条件的元素,返回一个筛选后的新数组
arr.filter(function(value, index, array){
// arr中有几项,该匿名回调函数就需要执行几次
// value —— 数组中的当前项
// index —— 当前项的索引
// array —— 原始数组
return xxx
})
// 例子:筛选出数组arr中所有负数
var arr = [1,-2,3,4,-5]
var minus = arr.filter(function(item,index,array){
return item < 0;
});
console.log(minus); // [-2, -5]
补充
(1)以上五大方法除了传递一个匿名函数作为参数之外,还可以传第二个参数,该参数用于指定匿名函数内的this指向
//例子
// 只传一个匿名函数
var arr = [1,-2,3,4,-5]
arr.forEach(function(item,index,array){
console.log(this); // window
});
// 传两个参数
arr.forEach(function(item,index,array){
console.log(this); // [1, -2, 3, 4, -5]
},arr);
(2)由于以上方法均属ES5方法,所以IE8及其以下浏览器均不兼容。
六、reduce()
arr.reduce(function(prev, cur, index, array){
// array——原数组
// prev——上一次调用回调时的返回值,或者初始值init
// cur——当前正在处理的数组元素
// index——当前正在处理的数组元素的索引
// init——初始值
}, init)
reduce实例
-
1)求数组项之和
var sum = arr.reduce(function (prev, cur) { return prev + cur; },0);
由于传入了初始值0,所以开始时prev的值为0,cur的值为数组第一项3,相加之后返回值为3作为下一轮回调的prev值,然后再继续与下一个数组项相加,以此类推,直至完成所有数组项的和并返回。
-
2)求数组项最大值
var max = arr.reduce(function (prev, cur) { return Math.max(prev,cur); });
由于未传入初始值,所以开始时prev的值为数组第一项3,cur的值为数组第二项9,取两值最大值后继续进入下一轮回调。
-
3)数组去重
var arr = [1, 1, 3, 4, 5, 8, 8, 9, 10, 10] var newArr = arr.reduce(function (prev, cur) { prev.indexOf(cur) === -1 && prev.push(cur); return prev; }, []); console.log(newArr) // [1, 3, 4, 5, 8, 9, 10]
补充:
||
或&&
两端是表达式-
1)
||
操作符从左开始判断表达式的真假,如果为真,返回左边表达式返回的值;如果为假,则继续判断右边的表达式 -
2)
&&
操作符从左开始判断表达式, 如果左边的表达式被判断为假, 这马上返回false, 不管右边的表达式是否为真;如果左边的表达式为真, 则继续判断右边的表达式, 然后返回右边表达式结果 -
// demo1 if(userName){ login(userName) }else{ signUp() } // 换成以下写法 userName && login(userName) || signUp()
-
// demo2 var userID; if (userName && userName.loggedIn) { userID = userName.id; } else { userID = null; } // 换成以下写法 var userID = userName && userName.loggedIn && userName.id
-
-
4)求字符串中字母出现的次数
let str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmx'; let res = str.split('').reduce( (hash, cur) => { hash[cur] ? hash[cur]++ : hash[cur] = 1 return hash }, {} )
-
5)将数组按一定的规则转成数组
// 每个值的平方 let arr = [1,2,3,4] let newArr = arr.reduce( (arr, cur) => { arr.push(cur * cur) return arr }, [] )
-
6)扁平一个二维数组
let arr = [[1, 2, 8], [3, 4, 9], [5, 6, 10]]; let res = arr.reduce((x, y) => x.concat(y), []);