js数组方法(es5)

js数组方法(es5)

ECMAScript 5定义了9个新的数组方法来遍历、映射、过滤、检测、简化和搜索数组。下面几节描述了这些方法。

但在开始详细介绍之前,很有必要对ECMAScript 5中的数组方法做一个概述。首先,大多数方法的第一个参数接收一个函数,并且对数组的每个元素(或一些元素)调用一次该函数。如果是稀疏数组,对不存在的元素不调用传递的函数。在大多数情况下,调用提供的函数使用三个参数:数组元素、元素的索引和数组本身。通常,只需要第一个参数值,可以忽略后两个参数。大多数ECMAScript 5数组方法的第一个参数是一个函数,第二个参数是可选的。如果有第二个参数,则调用的函数被看做是第二个参数的方法。也就是说,在调用函数时传递进去的第二个参数作为它的this关键字的值来使用。被调用的函数的返回值非常重要,但是不同的方法处理返回值的方式也不一样。ECMAScript 5中的数组方法都不会修改它们调用的原始数组。当然,传递给这些方法的函数是可以修改这些数组的。

forEach

  forEach方法用于遍历数组,并进行相应操作。它有一个必填参数,这个参数是一个回调函数,这个函数有3个参数,依次是:当前遍历到的数组元素(item)、当前的数组元素的索引值(index)、当前操作的数组对象(curArr);后两个参数可选,第一个参数必填,这个回调函数没有返回值。

var arr1 = [1,2,3,4,5];
arr1.forEach((item, index, curArr) => {
    curArr[index] = item*item;
});
// arr1 //[1, 4, 9, 16, 25]

  forEach方法会改变原数组,而且它不会提前终止遍历,即会把数组的每一项都遍历之后才会结束运行,所以即使报错也不会终止该方法,需要把forEach方法放到一个try代码块中,并能抛出一个异常,如果forEach方法调用的函数抛出foreach.break异常,那么遍历会终止。

map

  map方法与forEach方法很相似,它有一个回调函数,回调函数有三个参数,1个必填,2个可选,依次是item、index、curArr。不同的是,map的回调函数应该有返回值。

  如果map的回调函数的 return 后面是一个变量表达式,那么map方法的返回值是进行对应操作后的新数组

var arr2 = [1, 2, 3, 4, 5];
var newArr1 = arr2.map((item,index,curArr)=>item * item); // 不加花括号是直接返回 => 后的值,当前数组的每一项都进行平方操作
// [1, 4, 9, 16, 25]
// arr2  // [1, 2, 3, 4, 5]

  如果map的回调函数的  return 后面是一个条件表达式,那么map方法的返回值是由当前数组的每一项对该条件的判定结果为true或false的数组项组成的子数组。

var arr2 = [1,2,3,4,5];
arr2.map(item => item<3)  //[true, true, false, false, false]

  还有一点与forEach方法不同的是,map方法不会改变原数组

 filter

  filter方法的参数结构跟 map 方法相似,不同的是,它的返回值是原数组的一个子数组,该子数组里面的数组项的属性值满足回调函数里的条件,即  filter 方法的返回值是由当前数组的每一项对该条件的判定结果为true时的数组项组成的子数组。

var arr3 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var newArr2 = arr3.filter((item,i,curArr)=>item < 6); // [1, 2, 3, 4, 5]
// arr3 // [1, 2, 3, 4, 5, 6, 7, 8, 9]

  filter方法还有一个特征是,filter不会遍历稀疏数组,也就是说,被省略的数组元素会被过滤掉,不参与条件判定,所以,filter返回的数组是一个密集数组。

var arr3 = [1,2,3,undefined,null,,,];
var newArr2 = arr3.filter((item, i, curArr) => {
     return item;
 }); // [1,2,3] 说明filter方法只会返回稠密数组,会过滤掉undefined和null

   filter方法不会修改原数组。

every && some

  every方法返回的是一个布尔值,当遍历的目标数组中的每一项都满足回调函数中的条件时才返回true,否则返回false,和逻辑运算中的“与”运算原理一致,一假则假。而且,every方法与forEach方法不同的是,every方法在运行到可以确定返回值的时候就会提前结束遍历。

var arr4 = [1,2,3,4,5];
var temp1 = [];
var result = arr4.every(item => {
    temp1.push(item);
    return item<3
    }); // false
 console.log(temp1); // [1,2,3] 说明遍历到3,就不满足条件,然后停止遍历了

  some方法与逻辑运算中的“或”运算原理一样,一真即真。也就是说,只要目标数组中有一个元素满足了回调函数中的条件,就返回true,只有全部都不满足时才返回false。some方法与every方法的遍历规则一样,只要能够确定返回值了就立刻终止遍历。

var temp2 = [];
var result2 = arr4.some(item => {
    temp2.push(item);
    return item<3
    }); // true
 console.log(temp2); // [1] 说明遍历到1,就满足了条件,于是停止遍历

  注意,当every和some方法的目标数组是一个空数组时,every方法返回的是true,some方法返回的是false

console.log([].every(item=>item)); // true
console.log([].some(item=>item)); //false

reduce && reduceRight

  reduce方法和reduceRight方法使用指定的函数将数组元素组合,生成单个值。

  reduce方法需要两个参数,第一个参数是执行化简操作的函数,化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回这个化简之后的值;第二个参数是执行化简操作的初始值,是一个可选参数,如果不写,则默认为数组的第一个元素。

var arr5 = [1,2,3,4,5];
var result3 = arr5.reduce((a,b) => a+b); // 15  (((1+2)+3)+4)+5

  两个数组元素为一组进行化简操作,最后得到的一个化简值又作为下一次化简操作的第一个操作数,以此类推,上述代码的功能就是对arr5数组里的元素做累加操作。

  reduceRight方法与reduce方法其实是一样的,但是他的化简操作是从右往左实现的。

[1,6,3,12].reduceRight((a,b)=> {return a-b}) // 2   // ((12-3)-6)-1

  值得注意的是,reduce方法和reduceRight方法再目标数组是一个空数组的情况下,第二个参数写与不写的结果是有很大区别的。

  当不写第二个参数时,会报错:

[].reduce((a,b) => a+b) // 报错 VM2095:1 Uncaught TypeError: Reduce of empty array with no initial value   
[].reduce((a,b) => a+b,1)  // 1

indexOf && lastIndexOf

  indexOf()和lastIndex0f()搜索整个数组中具有给定值的元素,返回找到的第一个元素的索引或者如果没有找到就返回-1。indexOf()从头至尾搜索,而lastIndexOf()则反向搜索。

a = [0,1,2,1,0];
a.index0f(1)    // 1, a[1]是1
a.lastIndexOf(1)   // 3, a[3]是1
a.indexOf(3)    // -1, 没有值为3的元素

  不同于上面描述的其他方法,indexOf()和lastIndexOf()方法不接收一个函数作为其参数。第一个参数是需要搜索的值,第二个参数是可选的:它指定数组中的一个索引,从那里开始搜索。如果省略该参数,index0f()从头开始搜索,而lastIndexOf()从末尾开始搜索。第二个参数也可以是负数,它代表相对数组末尾的偏移量,对于splice()方法:例如,-1指定数组的最后一个元素。

原文地址:https://www.cnblogs.com/lindang/p/14154033.html