javaScript数组之常用方法

今天继续接着上一篇的数组循环,来继续分享数组的常用方法,上章分享过的本章节里就不在重复了。下面请看代码:

  • push(), unshift()
  • pop(), shift()
  • join(), concat(), reverse()
  • slice()
  • splice()
  • sort()
  • toString()
  • Array.from(), Array.of(), isArray()
  • find(), findIndex()
  • indexOf(), includes()
  • reduce()

push()和unshift()

push:向数组的末尾添加一个或更多元素,并返回新的长度;unshfit:向数组的开头添加一个或更多元素,并返回新的长度,这两个方法的使用也很简单,就是把你需要添加进去的数据作为参数放在括号里就OK了,下面看例子: `

var arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
var objOne = {num:40, color: 'green'}, objTwo = {num:50, color: 'golden'}
var len = arr.push(objOne, objTwo);
console.log(arr, len);
// 输出: [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'},
// {num:40, color: 'green'}, {num:50, color: 'golden'}], // 输出:5
复制代码

`

这个例子里呢,我给数组push了两个对象,这里就有一个我们使用这个方法唯一需要注意的问题,新添加进去的数据的顺序问题,push方法里的第一个参数是紧跟在arr原数组的最后一个位置,后面的又紧跟在刚添加进去的那个数据后面,而如果是unshift呢,它的顺序则是这样 [{num:40, color:'green'}, {num:50, color: 'golden'},{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'},第一个数据在最前面,第二个跟在前一个数据的后面,然后才是原数组arr排序。而我们这个例子里的len呢,是添加数据进去后,返回的这个arr数组最新的长度值。

pop()和shift()

pop:删除数组的最后一个元素,并返回被删除的元素;shift:删除数组的第一个元素,并返回被删除的元素。这两个方法的使用也是超级简单,下面看例子: `

var arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
var del = arr.pop();
    console.log(arr, del);
    // 输出:[{num:10, color: 'red'}, {num:20, color: 'yellow'}]
    // 输出:{num:30, color: 'blue'}  //这个是被删除的元素
复制代码

`而这两个方法的使用需要注意的是两点,一:它们不接收参数,你们可以试着给它们俩传递个参数进去,不管啥类型,这俩方法它也不会报错,照常执行;二:它们会改变原数组;

join(), concat(), reverse()

join: 用指定的分隔符号,把数组转换成字符串,concat:连接两个或更多的数组,并返回连接的结果,reverse:颠倒数组里的前后顺序; `

var arr = [10, 20, 30], ary = [40, 50, 60]
var arrStr = arr.join('-');
console.log(arr, arrStr)
// 输出:"10-20-30", [10, 20, 30]

var arry = arr.concat(ary);
console.log(arry, arr)
// 输出: [10, 20, 30, 40, 50, 60],  // 原数组不会改变 [10, 20, 30]

var newArr = arr.reverse();
console.log(arr, newArr);
// 输出:[30, 20, 10], [30, 20, 10]
newArr[0] = 'ABC'
console.log(arr, newArr);
// 输出:['ABC', 20, 10], ['ABC', 20, 10]
复制代码

` 上面的代码我对三个方法都做了演示,通过代码示例,现在我们来总结使用的经验:

  • 一:join是用指定的分隔符号,把数组转换成字符串,并返回出这个字符串,但是不会影响原数组;
  • 二:concat是连接两个或更多的数组,并返回连接的结果,连接的结果是个新数组,同样不会影响原数组;
  • 三:reverse颠倒数组的里前后顺序,可以接收一个返回结果,但是这个返回结果就是被颠倒顺序后的原数组。

slice()

slice,截取数组里的片段,并把截取的片段作为新数组返回;slice接收两个参数,第一个参数是截取的开始位置,第二个是截取的结束位置,都不是必填参数。 `

var arr = [10, 20, 30, 40, 50]; 
var newArr1 = arr.slice(0, 3);
console.log(newArr1, arr);
// 输出: [10, 20, 30], [10, 20, 30, 40, 50]

var newArr2 = arr.slice(0, 100);  
console.log(newArr2, arr);
// 输出: [10, 20, 30, 40, 50], [10, 20, 30, 40, 50]

var newArr3 = arr.slice(-1, 3); 
console.log(newArr3, arr);
// 输出: [], [10, 20, 30, 40, 50]

var newArr4 = arr.slice(3);
console.log(newArr4, arr);
// 输出: [30, 40, 50], [10, 20, 30, 40, 50]

var newArr5 = arr.slice();
console.log(newArr5, arr);
// 输出: [10, 20, 30, 40, 50], [10, 20, 30, 40, 50]
复制代码

` 这个例子里演示了五种截取状态,在这里我们唯一需要注意的是两点,一:如果我们slice()里一个参数都不填,那等于就是复制原数组了;二:slice操作是不会影响原数组的。

splice()

splice,对数组执行删除元素或者添加元素的操作,接收三个参数,第一个是对数组操作的起始位置(包含起始位置),第二个是你要对数组删除的操作,(1表示删除一个,0表示不删除),第三个是你要新增的元素。正因为splice有这几个特性,你对数组的操作便可以实现多样化,删,增或者替换: `

var arr = [10, 20, 30, 40, 50]
var delArr = arr.splice(0, 1);  // 删除演示
console.log(delArr1, arr);
// 输出:[10], [20, 30, 40, 50]

arr.splice(0, 0, 5); // 新增演示
console.log(arr);   
// 输出:[5, 20, 30, 40, 50]

arr.splice(0, 1, 10);    // 替换演示
console.log(arr);
// 输出:[10, 20, 30, 40, 50]
复制代码

` 这里需要特别说明的就是,splice的操作是会影响原数组的,splice删除的元素也可以返回出来,是以一个新数组接收的,但是基本上我们在工作当中,不会对它删除的这个元素做什么处理,所以基本没有什么用。

sort()

sort,对数组元素进行排序,sort接收一个参数,该参数是个回调函数,我们一般称之为比较函数,比较函数里接收两个参数,称之为比较值。 `

var arr = [40, 20, 50, 100, 30], ary = ['c', 'a', 'e', 'b', 'd'];
arr.sort(); ary.sort();// 不传入比较函数
console.log(arr, ary);
// 输出 [100, 20, 30, 40, 50], ['a', 'b', 'c', 'd', 'e']
复制代码

` 在不传入比较函数的情况下,数字的排序其实是根据数字的123456789进行一个升序的排序,数字这样的排序是不准确的,因为如果一大大于个位数,就会出现我们上面例子的情况。字母则是英文26个字母的排列顺序;

`

var arr = [40, 20, 50, 100, 30], ary = ['c', 'a', 'e', 'b', 'd'];
arr.sort(function(a, b){
    return a - b; // 传入比较函数
}); 
ary.sort(function(a, b){
    return a - b; // 传入比较函数
}); 
console.log(arr, ary);
// 输出 [20, 30, 40, 50, 100], ['a', 'b', 'c', 'd', 'e']
复制代码

` 传入比较函数,sort方法会去循环这个数组,每次去取数组当前位和下一位根据规则进行比较;字符串则根据Unicode码的大小来比较。而对于中文汉字,sort也是可以实现排序的,传入比较函数它的排序规则是根据汉字的拼音字母顺序排序,不传则是Unicode码的大小来排序。

`

arrStr = ['我', '和', '你', '心', '相', '应']
arrStr.sort();  // 不传入比较函数
console.log(arrStr);
// 输出 ["你", "和", "应", "心", "我", "相"]
arrStr.sort(function(s1, s2){
    return s1.localeCompare(s2); // 传入比较函数
}); 
console.log(arrStr);
// 输出 ["和", "你", "我", "相", "心", "应"]
复制代码

` 在汉字排序的时候,我们会使用一个字符串的方法localeCompare,该方法大家可以先去w3c上面去了解下。

toString() toString,方法可把数组转换为字符串,并返回这个字符串结果,注意,返回的字符串以英文逗号分隔,并且并不影响原数组。 `

var arr = [10, 20, 30, 40, 50];
var arrStr = arr.toString();
console.log(arr, arrStr);
// 输出: [10, 20, 30, 40, 50], "10,20,30,40,50"
复制代码

`

Array.from(), Array.of(), isArray()

Array.from,Array.of,Array.isArray这三个方法都是es6里新增的方法,这三个方法使用的第一条注意事项就是,它们不是生成的实例对象的方法,而是构造函数Array这个类的方法。好啦,下面一一介绍:Array.from:方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象: `

    

p1

p2

p3

复制代码

` 只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组,例如字符串也具备Iterator接口,所以也可以转数组:

`

let str = 'javascript';
let strArr = Array.from(str);
console.log(strArr)
// 输出 ['j', 'a', 'v', 'a', 's', 'c', 'r', 'i', 'p', 't']

let testSet = new Set(['a', 'b', 'c'])  // set数据类型转数组
console.log(Array.from(testSet))
// 输出 ['a', 'b', 'c']
复制代码

` Array.from方法支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组。Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

`

let str = 'javascript';
let strArr = Array.from(str, (item) => {return item.toLocaleUpperCase()});
console.log(strArr)
// 输出 ["J", "A", "V", "A", "S", "C", "R", "I", "P", "T"]
复制代码

` Array.of方法用于将一组值,转换为数组,这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

`

Array.of(1, 2, 3) // [1, 2, 3]
Array.of(3) // [3]
Array.of(3).length // 1

Array() // []
Array(3) // [, , ,] // 因为参数为一个数,Array则把它定义成数组长度了
Array(1, 2, 3) // [1, 2, 3]
复制代码

` Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。

Array.isArray,是用来检测对象是否是一个真正的数组,返回一个布尔值,true或者false。

`

var ar = [];
var result = Array.isArray(ar);
// 输出: true

var ar = new Array();
var result = Array.isArray(ar);
// 输出: true

var ar = [1, 2, 3];
var result = Array.isArray(ar);
// 输出: true

var result = Array.isArray("an array");
document.write(result);
// 输出: false
复制代码

`

find()和findIndex()

find用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined: `

let arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
let val = arr.find(function (item) {
            console.log(arguments)  //接收三个参数,item当前项,索引值,原数组
            if (item.num == 20) {
                return item
        }
    })
    console.log(val)    // 输出 {num:20, color: 'yellow'}
复制代码

` findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

`

let arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
let idx = arr.findIndex(function (item) {
        console.log(arguments)  //接收三个参数,item当前项,索引值,原数组
        return item.num == 20
    })
    console.log(idx)    // 输出 1
复制代码

`

indexOf()和includes()

indexOf 方法在数组中搜索指定的值。该方法返回第一个匹配项的索引;如果找不到指定的值,则为 -1;该方法接收两个参数,参数一是需要查找的对象,参数二是从数组哪里开始查找,也就是数组的索引值: `

let webBasic = ['html', 'css', 'javascript', 'es6', 'jquery'];
webBasic.indexOf('javascript') //输出 2, 默认从数组索引0开始搜索
webBasic.indexOf('javascript',1) //输出 2, 从数组索引1开始搜索
webBasic.indexOf('javascript',3) //输出 -1, 从数组索引3开始搜索
复制代码

` includes方法返回一个布尔值,表示某个数组是否包含给定的值,如果存在给定值,则返回true,不存在false,该方法同样接收两个参数,参数一是需要查找的对象,参数二是从数组哪里开始查找:

`

let webBasic = ['html', 'css', 'javascript', 'es6', 'jquery'];
webBasic.includes('javascript') //输出 true, 默认从数组索引0开始搜索
webBasic.includes('javascript',1) //输出 true, 从数组索引1开始搜索
webBasic.includes('javascript',3) //输出 false, 从数组索引3开始搜索
复制代码

` 大家是不是觉得这两个方法功能非常相同,功能几乎一样,这里先说明下,indexOf是es5就有的方法了,includes是es6的方法,也就是说这两个方法不是同一个版本推出来的方法。indexOf在使用的过程中,其实存在一定的不足,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判,而includes则不存在这样的问题:

`

[NaN].indexOf(NaN)  // 输出-1
[NaN].includes(NaN) // 输出true
复制代码

` 这里在给大家补充一点对于这两个方法使用的注意事项和小技巧,这两个方法在使用的过程中,对一维数组的使用效果非常的好,但是对于二维数组或者其他多维就不怎么靠谱了。在我上一篇的数组循环的分享时,有提到过一嘴,这两个方法的使用一般都会结合map这类循环方法,为啥这么说呢,因为在我们日常工作当中,我们所处理的数组几乎都是多维数组,下面请看例子:

`

let arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
arr.indexOf({num:20, color: 'yellow'})     // 输出-1
arr.includes({num:20, color: 'yellow'})    //  输出 false

let ary = arr.map((item) => {
    return item.num
})
ary.indexOf(20) // 输出 1
ary.includes(20)    // 输出 true
复制代码

` 上面的例子我们可以看到,我们去查询一个对象的时候,它们的输出就都错了,而我们之所以结合map方法来使用,其目的就是要把我们需要查询的数组转换为一个一维数组。

reduce()

reduce方法对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供。其实说的简单一点,这个方法就是对数组里的值做累积计算的,当然一般都是用来对数字做累积计算,下面看例子: `

let numArr = [10, 20, 30, 40, 50]
let total = numArr.reduce((result, num)=>{
    console.log(arguments)  //arguments输出看下面的图片
    return result + num
})
console.log(total)  // 输出 150
复制代码

`

; 通过上面的例子和图片,我们可以看到,reduce对数组里累加的一个结果,它传递了一个回调函数参数,它的回调函数默认四个参数,该回调函数会循环遍历这个数组, 参数一是默认累加的结果值,参数二是循环这个数组的第一轮累加的当前项,默认数组0位开始;参数三是数组索引,参数四是原数组。reduce方法还可以传入第二个参数,这个参数就是累加的初始值:

`

let numArr = [10, 20, 30, 40, 50]
let total = numArr.reduce((result, num)=>{
    console.log(arguments)  //arguments输出看下面的图片
    return result + num
}, 50)
console.log(total)  // 输出 200
复制代码

` 大家在使用这个方法的时候,在多维数组的使用时,请一定看清楚上面对回调函数参数的说明,避免出错。这里也示例一下:

`

let arr = [{num:10, color: 'red'}, {num:20, color: 'yellow'}, {num:30, color: 'blue'}];
arr.reduce((result,item) =>{ return result + item.num })    // 输出60
复制代码

`

结语 对数组方法的分享到今天算是告一段落,后面会补充一个数组去重分享。在我们日常的工作开发中,数组应用非常频繁,需要我们更多的去熟悉数组方法应用的,对数组方法细节的把握。这里在分享一个链接,大家想了解更多数组

你可能感兴趣的:(javaScript数组之常用方法)