相关文章推荐
干练的西装  ·  js ...·  2 月前    · 
风流的板栗  ·  香港閱讀城·  1 年前    · 
考研的台灯  ·  OH 3.3.0 Frontail not ...·  1 年前    · 
知识渊博的斑马  ·  Excel ...·  2 年前    · 
自信的胡萝卜  ·  Nosql-neo4j-Cypher 语句 ...·  2 年前    · 

JS数组的常用方法

文章开始前先唠叨两句,最近工作实在太忙了,天天干到深夜,实在没时间来做知识分享,今天带来这篇JS中数组常用的方法,也是平时工作中的一些总结的方法吧,熟练使用会大大提高开发效率,我们一起来看看这些方法。

创建数组

通常创建数组有两种方式,分别为构造函数方式与数组字面量方式,而构造函数方式创建数组有个缺陷,当参数为一个数值的时候,会把这个数值当做数组的长度,创建这个一个长度为数值的字符串,其每个元素的值都为空,ES6的扩展方法中可以解决该问题,我放到下文来介绍。

检测数组

数组可以使用instanceof和Array.isArray()这两种方式去检测,用instanceof检测数组时,它的左边为被检测数组,右边为需要检测的类型,即Array;而Aarry.isArray()来检测数组时,该方法接收一个参数,这个参数就是被检测的数组。这两个方法返回的都是一个boolean类型的值,true为数组类型,false为非数组类型,来看看例子:

// 1.instanceof
var a = new Array(); // true
console.log( a instanceof Array);
// 2.Array.isArray()
console.log(Array.isArray(a)); // true

转换方法

  1. toString():该方法会返回数组中每个值的字符串形式以逗号隔开组成的字符串。
  2. valueOf():该方法返回数组本身
  3. toLocaleString():该方法返回一个数值以逗号隔开的字符串
  4. join():join方法是把数组转为字符串,其接收一个参数,这个参数即数组值之间的分隔符,如果参数为undefined或者不传,则默认逗号分隔。

上面三个数组转字符串的方法均有个共同点,当数组中某一项为null或则undefined时,则这一项都以空字符的方式被转出。来看看下面的例子:

// 1.toString()
var a = [1,2,3,null,,'菜鸟', '大佬'];
console.log(a.toString());
// 2.valueOf()
console.log(a.valueOf());
// 3.toLocaleString()
console.log(a.toLocaleString());
// 4.join()
console.log(a.join(''))

打印结果如下:

栈与队列

  1. push():push()方法是向数组的末尾添加项,只需把需要添加的项传入其参数中,就会添加到数组末尾,并返回数组的长度。
  2. pop():pop()方法用以移除数组末尾的项,并返回移除项的值。
  3. unshift():unshift()方法是向数组的首部添加项,与push()相似,同样把需添加的项传入参数,并返回数组的长度。
  4. shift():shift()方法与pop()类似,它是用以移除数组的首项,返回移除项的值。

来看看下面的例子:

// 1.push()
var a = ['首项',1,2,3,,'菜鸟', '大佬'];
console.log(a.push('Jacob','JS'),a)
// 2.pop()
console.log(a.pop(),a)
// 五、队列
// 1.shift()
console.log(a.shift(),a)
// 2.unshift()
console.log(a.unshift('添一个'),a)

打印结果如下:

观察打印结果,每一条数据的左边为方法的返回值,右边为原数组,这些方法都会改变原数组,所以在使用的时候一定要注意。

数组操作

  1. concat():该方法用以合并数组,把需要合并的数组以参数传入,返回合并后的新数组,不改变原数组,来看例子:
var a = [1,2,3,,'菜鸟', '大佬'];
var b




    
 = ['JS','Vue','html'];
console.log(a.concat(b), b.concat(a), a)
// [1, 2, 3, empty, "菜鸟", "大佬", "JS", "Vue", "html"]
// ["JS", "Vue", "html", 1, 2, 3, empty, "菜鸟", "大佬"]
// [1, 2, 3, empty, "菜鸟", "大佬"]


2. slice():该方法用以提取数组中的指定位置元素并将这些提取出的原数组成新数组返回,不改变原数组。看下面的例子:

var a = [1,2,3,,'菜鸟', '大佬'];
console.log(a.slice(1), a.slice(1, 5), a)
// [2, 3, empty, "菜鸟", "大佬"]
// [2, 3, empty, "菜鸟"] 
// [1, 2, 3, empty, "菜鸟", "大佬"]

从这个例子看出,slice()接收一个参数时,表示从下标为该参数值开始一直到数组末尾的所有项都提取出来;而接收两个参数时,表示从下标为参数1的值开始一直到下标为参数2的值的前一项的所有项都提取出来。总的来说就是提取数组项时会包括开始位置,但不包括结束位置。

3. splice():splice()方法我个人认为是数组中最强大的一个方法,它可以做到插入、删除以及替换数组中的项,来分别看看这三种操作如何实现。

删除:splice()方法用以删除项时,其接收两个参数,第一个参数是删除的开始位置,第二个参数是要删除的个数,删除后会返回被删除的项组成的数组,且会改变原数组,请看下面这段代码:

var a = [1,2,3,,'菜鸟', '大佬'];
console.log(a.splice(0,2), a)
// [1, 2]  [3, empty, "菜鸟", "大佬"]

上面代码中,通过splice()方法删除数组a中的位置0开始的两个项,并返回了这两个项组成的新数组,且原数组发生了改变。

插入:splice()方法用以插入时接至少接收3个参数,其中第一个参数为插入开始位置,第二个参数固定值为0,表示仅插入,第三个参数或后面的参数,即为需要插入的项,来看代码:

var a = [1,2,3,,'菜鸟', '大佬'];
console.log(a.splice(4,0,'VUE','JS'), a)
// []   [1, 2, 3, empty, "VUE", "JS", "菜鸟", "大佬"]

上面例子中,依次在数组的下标4的位置添加了2个项,返回了空数组,空数组表示原数组中没有被替换或删除的项。插入操作也会改变原数组。

替换:splice()方法用以替换时与用以插入时相似,唯一不同的就是第二个参数不能为0,此时第二个参数表示被替换项的个数,将上一个例子稍作修改:

console.log(a.splice(4,2, 'HTML'), a)
// ["菜鸟", "大佬"]  [1, 2, 3, empty, "HTML"]

此时splice()方法返回了一个数组,仔细看,这个数组的两个项都是原数组中下标为4与5的项,那么得出结论,此时的第二个参数就为替换的个数。

位置查找

  1. indexOf():indexOf()方法用以找出数值中第一个匹配项的下标位置并返回,如果整个数组中都没有找到匹配项,则返回-1
  2. lastIndexOf():该方法与indexOf()方法的查询方向相反,它是从数组末尾向首部遍历查询,如果查找到第一项,就返回其下标位置,如果一直没找到则返回-1

这两个方法还可以接收第二个参数,表示查询的起始位置,如果存在第二个参数,就会从该位置一直找到最后,当找到第一个匹配的时候停止。来看例子:

// 1.indexOf()
var a = [1,2,3,,'菜鸟', '菜鸟', '大佬'];
console.log(a.indexOf('菜鸟',2))  // 4
// 2.lastIndexOf()
console.log(a.lastIndexOf(3, 1))  // -1

上面例子中分别输出4与-1,indexOf()方法中是从下标2的位置开始向末尾查找,找到下标为4的时候发现了第一个匹配项,返回该下标;而lastIndexOf()中是从下标为1的位置向首部查找,未查找到匹配项,返回-1。

迭代方法

迭代方法,说白了就是数组的遍历方法,而这些方法都有自己在遍历之后对数据的处理方式,下面来分别介绍这些方法。

  1. every():every()方法需数组项中每一项都满足指定条件才能返回true;
  2. filter():filter()方法用于过滤出数组中满足条件的项,并组成新的数组返回;
  3. forEach():forEach()是我个人比较喜欢用来遍历数组的方法,它遍历了数组之后,不会返回任何值;
  4. map():map()和forEach有些类似,但是map会返回参数函数操作后的结果组成的数组;
  5. some():some()方法只要数组项中有一个满足指定条件,就会返回true。

来看看以下例子:

// 1.every()
var a = [1,3,5,4,2,7,6];
var result = a.every(function(n){
  return n >= 1 ? true : false;
console.log(result)
// 2.filter
result = a.filter(function(n) {
  return n > 3 ? true : false;
console.log(result)
// 3.forEach
result = []
a.forEach(n => {
  result.push(n * 10)
console.log(result)
// 4.map
result = []
result = a.map(n => {
  return n + 1
console.log(result)
// 5. some
result = a.some(n => {
  return n > 6 ? true : false
console.log(result)

打印结果如下:

归并方法

  1. reduce():reduce()方法接收1个参数函数,改参数函数又接收4个参数,第一个参数为上一次归并的值,第二个参数为当前值,第三个参数为当前下标,第四个参数为该数组本身。
  2. reduceRight():该方法与reduce的主要作用一样,其区别在于执行方向相反,reduceRight()是从右向左,而reduce()是从左向右。来看看下面这个例子:
// reduce
var a = [1,3,5,4,2,7,6];
var result = a.reduce((up, now, index, arr) => {
  return now + up
console.log(result) // 28
// reduceRight
result = a.reduceRight((up, now, index, arr) => {
  return up - now
console.log(result) // -16

ok,以上E5及以前的数组方法就介绍这么多,接下来看看ES6中数组的一些常用扩展方法。

数组扩展

数组的扩展方法主要是ES6中的几个扩展方法,下面来分别看看这些方法。

  1. 扩展运算符:扩展运算符用3个点(…)表示,将一个数组转为用逗号分隔的参数序列,它的后面还可以放置表达式,如果扩展运算符后面是一个空数组,则没有任何值。

扩展运算符有很多应用场景,下面来说说几个常用场景。

合并数组:在ES5中,合并数组可以采用concat()方法,这个方法我在上面也进行了介绍,而如果用扩展运算符来合并数组的话,在写法上会更加灵活。

解构赋值:解构赋值结合扩展运算符,是实际开发中经常用到的,用起来也是爽得飞起的。

字符串转数组:将一个连续的字符串直接转为数组,字符串的每个字符对应数组中的项。

作为函数返回值:在ES5及其之前,函数的返回值只能一个,如果想要返回多个值,则要把这些值保存在数组或则对象中来返回,而这里采用扩展运算符时,则可以一次性返回多个值

下面来看一个例子:

function fn() {
  // 解构赋值
  var [index, ...arg] = [...arguments];
  console.log(index,arg);
  // 合并数组
  arg = [index, ...arg];
  console.log(arg);
  // 字符串
  var str = 'cainiao';
  // 函数返回值
  return [...str, ...arg]
var arrStr = fn(1,2,'',3,4);
console.log(arrStr)

例子中我定义了一个函数,在函数中把这些场景都实现一遍,来看看打印结果:

先看第一次打印,打印出了变量index和数组arg,正确的体现了解构赋值的特性,没问题;第二次打印了将变量index与数组arg合并后的的值,也就是原参数数组,没问题;第三次打印,将字符串str拆分为数组再与数组arg合并,并返回到外部作用域打印出来,结果没问题。

2. Array.from():Array.from()方法用以将数组型对象转换为真正的数组,数组型对象的键名是从0开始递增的数值,且拥有length属性,length属性表示长度。Array.from()可接收两个参数,第一个参数为需要转换的对象,第二个参数为函数,这个函数中可以对被转换对象的每个属性进行操作,我们来看这个例子:

var obj = {
  0: '菜鸟',
  1: '学习',
  2: '18',
  length: 3
var objArr = Array.from(obj, item => {
  return item + '@'
console.log(objArr) // ["菜鸟@", "学习@", "18@"]

这个例子通过Array.from()方法把对象的每一个属性值加了一个@字符之后,再返回了一个真正的数组。

3. Array.of():Array.of()方法用以弥补Array()构造函数创建数组时的缺陷。当Array()构造函数创建数组时,参数传递单个数值时,它会创建长度为参数数值的每一项为空的数组,而Array.of()则解决了这个问题,它是将这个数值作为项创建一个数组,来看这段代码:

var arr = new Array(3);
var a = Array.of(3);
console.log(arr, a) // [empty × 3]  [3]

这里打印结果中的empty *3表示3个连续的空项。

4. find()与findIndex()

这两个方法都是找出数组中的匹配项,它们都接收一个函数参数,该函数中可以自定义匹配条件,找出第一个匹配的项就返回。而它们的区别就在于返回值,find()方法返回的是匹配项的值,如果没找到就返回undefined,而findIndex()方法返回的是匹配项的下标,如果没找到就返回-1,是不是和indexOf()方法很像,来个例子:

var a = [,1,2,3,,'菜鸟', '大佬', '菜鸟', '大佬'];
console.log(a.find(item => {
  return item == "菜鸟";
}), a.findIndex(item => {
  return item == "大佬"
// 菜鸟 6

数组中存在两个相同值而位置不同的项,但是只找出了最近的那个,结果没问题

5. fill()

fill有填充的意思,在这里的fill()方法也正是这个意思,它可以向数组中填充自定义元素,它接收3个参数,第一个参数需要填充的项值,第二个参数为填充的起始位置,第3个参数为填充结束的后一个位置,也就是该位置的前一个位置就是结束位置,来段简单的代码:

var a = [,1,2,3,,'菜鸟', '大佬', '菜鸟', '大佬']
a.fill('JS', 3, 4);
console.log(a) // [empty, 1, 2, "JS", empty, "菜鸟", "大佬", "菜鸟", "大佬"]

这段代码的意思是将“JS”这项填充到数组a的下标3的位置。

6. entries()、keys()以及values()

这三个方法是ES6中扩展的数组迭代方法,entries()是对键值对遍历,keys()是对键名遍历,而values()是对键值遍历。来看下面这个例子:

for (let [item,index] of a.entries()) {
  console.log(item, index)
for (let item of a.values()) {