JavaScripts基础(6)数组常用方法全解读

260 阅读14分钟

数组也是对象数据类型,也是由键值对组成

1、以数字作为索引(属性名),索引从0开始递增

2、有一个length的属性存储的是数组的长度

数组中每一项都可以是任何数据类型

arr[0] 获取第一项

arr[arr.length-1] 获取最后一项

splice改变、slice查找

1.1-1.4新增返回长度,删除返回删除项

slice参数都是索引值

var arr=[12,12,15]
/*
*结构:
*	0:12
*	1:12
*	2:15
*	length:3
*/
1、以数字作为索引(属性名),索引从0开始递增
2、有一个length的属性存储的是数组的长度

数组中的常用方法

按照四个维度记忆:

  • 方法的作用
  • 方法的参数
  • 方法的返回值
  • 原有数组是否改变

push

  • 作用:向数组“末尾”追加新的内容
  • 参数:追加的内容(可以是一个,也 可以是多个)
  • 返回值:新增后数组的长度
  • 原有数组:改变
var arr=[12,23,42]
console.log(arr.push(100))   //4
console.log(arr)             // [12,23,42,100]
console.log(arr.push(200,300))   //6

//别的实现方式向数组“末尾”追加新的内容
ary.splice(arr.length,0,100)
arr[arr.length]=100

pop

  • 作用:删除数组最后一项
  • 参数:无
  • 返回值:被删除的那一项内容
  • 原有数组:改变
var arr=[12,23,42]
console.log(arr.pop())   //42
console.log(arr)             // [12,23]

//别的实现方法删除最后一项
arr.splice(arr.length-1)
arr.length--
最好不要使用

unshift

  • 作用:向数组开始位置追加新内容
  • 参数:要新增的内容
  • 返回值:新增后数组的长度
  • 原有数组:改变
var arr=[12,23,42]
console.log(arr.unshift(100,true))   //5
console.log(arr)             // [100,true,12,23,42]

shift

  • 作用:删除数组第一项
  • 参数:无
  • 返回值:被删除的那一项内容
  • 原有数组:改变
  • shift()删除第一项以后,原有后面每一项的索引都向前减一
var arr=[12,23,42]
console.log(arr.shift())   //12
console.log(arr)             // [23,42]

splice(n,m,x...):改变,起始位置n后面的m个,包含第n个m个内容

1、删除arr.splice(n,m)

  • 从索引n开始(包含第n个),删除m个内容,
  • 返回值:把删除的部分以一个新数组返回
  • 原有数组:改变
  • 如果不指定m,或者删除的个数大于最大长度,都是删除到数组的末尾
var arr=[12,23,34,45,56,78]
console.log(arr.splice(2,3))   //[34,45,56]
console.log(arr)             // [12,23,78]

//第二个参数不传删除到末尾
var arr=[12,23,34,45,56,78]
console.log(arr.splice(2))   //[34,45,56,78]
console.log(arr)             // [12,23]

2、 增加内容arr.splice(n,0,x...)

  • 从索引n开始删除0项(没删除),把X或者更多需要插入的内容放到数组中n的前面
  • 返回值是空数组 [] (因为一项也没删除)
var arr=[12,23,42]
console.log(arr.splice(1,0,'哈哈哈','bbb'))   //[]
console.log(arr)             // [12,'哈哈哈','bbb',23,42]

3、修改arr.splice(n,m,x...)

  • 修改的原理:把原有内容删除掉,然后用新的内容替换掉这部分内容
  • 返回值:把删除的部分以一个新数组返回
var arr=[12,23,34,45,56,78]
console.log(arr.splice(2,3,'aaa','bbb'))   //[34,45,56]
console.log(arr)             // [12,23,'aaa','bbb',78]

slice(n,m):查找,起始位置到结束位置,包含第n项不包含第m项

  • 作用:在一个数组中,按照条件查找出其中的部分内容
  • 参数:两个参数(n,m)n和m都是索引,m不代表向后查几项)从索引n开始找到索引m处(包含第n项不包含第m项
  • 返回值:以一个新数组存储查找的内容
  • 原有数组:不改变
  • m不写查找到最后一项
  • 数组克隆:n写0m不写, 或者mn都不写和原有数组一样,但是不是相同的堆内存空间,两个数组不相等,相互独立,遇到非基本类型只是简单赋值引用,所以是 浅拷贝
  • 支持负数:用总长度加上负数来进行索引,n要比m小
var arr=[12,23,34,45,56,67,78,8990]
console.log(arr.slice(2,7))   //[34,45,56,67,78]  从索引2开始找到索引7处
console.log(arr)             // [12,23,34,45,56,67,78,89,90]

//查找到最后一项
var arr=[12,23,34,45,56,6778,8990]
console.log(arr.slice(2))   //[34,45,56,67,78,89,90] 
console.log(arr)             // [12,23,34,45,56,67,78,89,90]
//数组克隆
var arr=[12,23,34,45,56,6778,8990]
console.log(arr.slice(0))   //[12,23,34,45,56,67,78,89,90] 
console.log(arr.slice())   //[12,23,34,45,56,67,78,89,90] 
//负数
var arr=[12,23,34,45,56,6778,8990]
console.log(arr.slice(-3,-1))   //[78,89] 

concat

  • 作用:实现多个数组(或者值)的拼接
  • 参数:数组或者值
  • 返回值:拼接后的新数组
  • 原有数组:不改变
var arr=[12,23]
var arr2=[100,200]
var arr3=[1000,2000]

console.log(arr.concat(arr2,'aaa',arr3)   //[12,23,100,200,'aaa',1000,2000]
console.log(arr)             // [12,23]

//可以基于空数组作为拼接的开始,在小括号中排列拼接顺序,空数组不会占用内容的位置,实现数组浅拷贝
[].concat(arr2,arr1,arr3)
		

toString

  • 作用:把数组转化为字符串
  • 参数:无
  • 返回值:数组中的每一项用逗号分隔的字符串
  • 原有数组:不改变
var arr=[12,23,42]
console.log(arr.toString())   //'12,23,42'
console.log(arr)             // [12,23,42]

join('xx'),把数组转化为字符串

  • 作用:和toString类似,把数组转化为字符串,但是我们可以设置变为字符串后,每一项之间的连接符
  • 参数:指定的连接符
  • 返回值:数组中的每一项用指定的连接符分隔的字符串
  • 原有数组:不改变
  • 不写连接符或者写为','跟toString一样

基于join实现数组求和:1、join('+') 2、eval:把字符串变为JS表达式执行,得到的是数组每一项的和

var arr=[12,23,42]
console.log(arr.join('+'))   //'12+23+42'
console.log(arr)             // [12,23,42]

//基于join实现数组求和
var arr=[12,23,42]

var arr2=arr.join('+')
console.log( arr2)   //'12+23+42'
console.log(eval(arr2))             // 77

reverse

  • 作用:把数组倒过来排列
  • 参数:无
  • 返回值:排列后的数组
  • 原有数组:改变
var arr=[12,23,42]
console.log(arr.reverse())   //[42,23,12]
console.log(arr)             // [42,23,12]

sort

  • 作用:给数组排序
  • 参数:无/函数
  • 返回值:排序后的新数组
  • 原有数组:改变
  • sort不传递参数时,只能处理10以内的排序
  • return a-b; //升序
  • return b-a; //降序
//sort不传递参数时,只能处理10以内的排序
var arr=[1,3,2,4,5,6,7,9,8]
console.log(arr.sort())   //[1,2,3,4,5,6,7,8,9]
console.log(arr)             // [1,2,3,4,5,6,7,8,9]
//大于10的数
var arr=[18,1,27,2,37,3]
console.log(arr.sort())   //[1,18,2,27,3,37]
console.log(arr)             // [1,18,2,27,3,37]

//sort传递function
arr.sort(function(a,b){
    return a-b;  //升序;  return  b-a为降序
})

var arr=[18,1,27,2,37,3]
console.log(arr.sort(function(a,b){
    return a-b;  //升序
}))   //[1,2,3,18,27,37]
console.log(arr.sort(function(a,b){
    return b-a;  //降序
}))   //[37,27,18,3,2,1]

indexOf / lastIndexOf(值)

这两个方法不支持IE低版本浏览器(IE6,7,8)

  • 作用:检测当前值在数组中第一次或者最后一次出现位置的索引,如果没有返回-1
  • 参数:要检测的值
  • 返回值:索引
  • 原有数组:不改变
  • 基于indexOf检测,如果数组中有这一项,返回大于等于0的索引,没有返回-1
	var arr=[12,23,42,51]
    console.log(arr.indexOf(42))   //2
    console.log(arr.indexOf(100))   //-1
    console.log(arr)             // [12,23,42,51]

	//验证数组中是否包含某一项
	if(arr.indexOf(100)>-1){
		//arr中包含100这一项
	}

arr.forEach(function(currentValue, index, arr){},thisArg)return不是必须的

不支持IE 6-8

作用:循环调用数组的每个元素,并将元素依次传递给回调函数

参数:

  1. 回调函数function(currentValue, index, arr){}:return不是必须的
  • currentValue:当前元素;
  • index:可选,当前元素的索引值;
  • arr:可选,forEach() 方法正在操作的数组。不会对空数组进行检测
  1. thisArg:可选参数。当执行回调函数时用作 this 的指向(参考对象)

返回值:无

原有数组:不改变

var sum = 0;
var numbers = [65, 44, 12, 4];
 
function myFunction(item) {
    sum += item;
}
console.log(numbers.forEach(myFunction))    //undefined
console.log(sum)     //125

array.map(function(currentValue,index,arr){},thisValue)必须有return

作用:

从左到右依次调用处理函数,返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值不会对空数组进行检测

参数:

  1. 处理函数:必须有return,数组中的每个元素都会执行这个函数
  • currentValue 必须 当前元素的值
  • index 可选 当前元素的索引值
  • arr 可选 当前元素属于的数组对象
  1. thisValue可选 对象作为该执行回调时使用,传递给函数,用作 "this" 的值

如果省略了 thisValue ,或者传入 null、undefined,那么回调函数的 this 为全局对象

返回值:

一个新数组,数组中的元素为原始数组元素调用函数处理后的值,'与原素组相比 每一项都变了'

原有数组:不改变

var numbers = [65, 44, 12, 4];

function multiplyArrayElement(num) {
    return num * document.getElementById("multiplyWith").value;
}

function myFunction() {
    document.getElementById("demo").innerHTML = numbers.map(multiplyArrayElement);
}

map与 parseInt结合 参考:js基础2、parseInt():转化为整数

let arr=[1,2,3]
console.log(arr.map(parseInt));			//[ 1, NaN, NaN ]

//parseInt分别接收到:
parseInt(1,0)	//当radix是0时 默认以10位基数   1
parseInt(2,1)	//当radix是小于 2 或者大于 36,则 parseInt() 将返回 NaN
parseInt(3,2)	//当radix是2 是以2进制计算 此时只有01是有效字符

arr.reduce(function(accumulator,currentValue,currentIndex,array){}, initialValue)计算、汇总、收敛需return

作用:

对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值

参数

1、callback参数:需return

  • accumulator累计器,累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)
  • currentValue:数组中正在处理的元素
  • currentIndex:可选,数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1
  • array:可选,调用reduce()的数组

2、initialValue:

作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素

在没有初始值的空数组上调用 reduce 将报错

如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行

返回值:函数累计处理的结果(返回的永远都是最后运算的结果

上次执行的结果会成为下一次的初始值

let arr=[1];
let num=arr.reduce((acc,cur)=>{
    return acc+cur;
})
console.log(num);  //1

let arr=[1,2];
let num=arr.reduce((acc,cur)=>{
    return acc+cur;
})
console.log(num);  //3

示例

计算数组中每个元素出现的次数:

将initialValue(初始值)设置为对象{},判断空对象中是否存在

acc初始值是指为了{}空对象;为累计器,累计回调的返回值

var arr=[1,2,3,4,5,6,1,1,2,4,5];
var aaa=arr.reduce((acc,cur)=>{
    if(cur in acc){
        acc[cur]++;
    }else{
        acc[cur]=1;
    }
    return acc;
},{})
console.log(aaa); //{ '1': 3, '2': 2, '3': 1, '4': 2, '5': 2, '6': 1 }

数组去重:

arr.sort先将重复的放在一起,所以只要重复 init[init.length-1] init最后一个肯定和下一个相等

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
//arr.sort先将重复的放在一起[ 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 5 ]
//所以只要重复  init最后一个(`init[init.length-1]`)肯定和下一个相等
// init 第1次循环时是 [],current 第1次循环时是 1
// init 第2次循环时是 [1],current 第2次循环时是 1
// init 第3次循环时是 [1],current 第3次循环时是 2
let result = arr.sort().reduce((init, current)=>{
    if(init.length===0 || init[init.length-1]!==current){
        init.push(current);
    }
    return init;
}, []);
console.log(result); //[1,2,3,4,5]

多层嵌套对象通过数组取值:

将取值对象传入当做初始值

let json={
    data:{
        name:'小明',
        msage:{
            age:18,
            hight:175
        }
    }
}
let arr=['data','msage','age'];  //先写出嵌套顺序,最终取到的是age

let value=arr.reduce((acc,cur)=>{
    return acc[cur];   //前边的对象直接被替换
},json)

console.log(value); //18

reduceRight 就是 reduce从右往左算

index 逐渐减小直至0

array.find(function(currentValue, index, arr){},thisValue)返回条件成立的数组的第一个元素的值

IE 11 及更早版本不支持 find() 方法,一般用于手机端

作用:

从左到右依次调用条件,返回条件成立的数组的第一个元素的值只找第一个,之后的值不会再调用执行函数;没有符合条件的元素返回 undefined;不会对空数组进行检测

参数:

1、执行的函数:必须返回条件值

  • currentValue 必须 当前元素的值
  • index 可选 当前元素的索引值
  • arr 可选 当前元素属于的数组对象;

2、 thisValue 可选 对象作为该执行回调时使用,传递给函数,用作 "this" 的值

返回值:返回条件成立的数组的第一个元素的值

原有数组:不改变

var ages = [3, 10, 18, 20];
 
function checkAdult(age) {
    return age >= 18;
}
var item=ages.find(checkAdult);
console.log(item)
//18   //返回条件成立的数组的第一个元素的值

array.findIndex(function(currentValue, index, arr), thisValue)返回数组中条件成立的第一个元素的索引

array.filter(function(currentValue,index,arr){},thisValue)返回条件成立的数组的所有元素组成的新数组

IE 9 以前不支持 filter() 方法

作用:

从左到右依次调用条件,返回条件成立的数组的所有元素组成的新数组,如果没有符合条件的元素则返回空数组;不会对空数组进行检测

参数:

1、 回调函数:必须有return

  • currentValue 必须 当前元素的值
  • index 可选 当前元素的索引值;
  • arr 可选 当前元素属于的数组对象;

2、 thisValue 可选 对象作为该执行回调时使用,传递给函数,用作 "this" 的值

  • 如果省略了 thisValue ,"this" 的值为 "undefined";

返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组

原有数组:不改变

function isBigEnough(element) {
  return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]

ES6:
 arg=arg.filter(item => !isNaN(item));

arr.fill(value)把数组的所有值都改写为value

var arr = [3, 10, 18, 20];
arr.fill(1)
console.log(ages);  //[ 1, 1, 1, 1 ]

arr.some(function(item){})只要有一个符合条件的元素就行

var arr = [3, 10, 18, 20];
let a=arr.some((item)=>{
    return item>22
})
console.log(a);  //false
let a=arr.some((item)=>{
    return item>19
})
console.log(a);  //true

arr.every(function(item){})每一个元素都必须符合条件才行

var arr = [3, 10, 18, 20];
let a=arr.every((item)=>{
    return item>18
})
console.log(a);  //false

var arr = [3, 10, 18, 20];
let a=arr.some((item)=>{
    return item>2
})
console.log(a);  //true

Array.from(arrayLike, mapFn, thisArg)将类数组转化为数组

  1. arrayLike:想要转换成数组的伪数组对象可迭代对象
  • 伪数组对象:(拥有一个 length 属性和若干索引属性的任意对象)
  • 可迭代对象:(可以获取对象中的元素,如 Map和 Set 等)
  1. mapFn (可选参数):如果指定了该参数,新数组中的每个元素会执行该回调函数
  2. thisArg (可选参数):可选参数,执行回调函数 mapFn 时 this 对象
  3. 返回值:一个新的数组实例
//字符串
Array.from('foo');   // ["f", "o", "o"]


//转化arguments类数组
function f() {
  return Array.from(arguments);
}
f(1, 2, 3);    // [1, 2, 3]

//使用箭头函数
Array.from([1, 2, 3], x => x + x);  
// x => x + x代表这是一个函数,只是省略了其他的定义,这是一种Lambda表达式的写法
// 箭头的意思表示从当前数组中取出一个值,然后自加,并将返回的结果添加到新数组中    
// [2, 4, 6]

function a(){
    Array.from(arguments).forEach((item)=>{
        console.log(item);      //1  2  3
    })
}
a(1,2,3)

Array.of(items)创建数组

let arr=Array.of(1)
console.log(arr);	//[1]

let arr=Array.of(1,2,3)
console.log(arr);       //[ 1, 2, 3 ]

还有很多:

  • includes
  • keys
  • ....

数组 类数组的区别:

  • 数组__proto__指向Array,所以能用Array的方法(push等)
  • 类数组__proto__指向Object,所以不能用Array的方法(push等)
  • 数组属于Array的一个类,类数组直属于Object的一个类不能用Array的方法