Skip to content

数组-Array

1.什么是数组

概念

英文:Array 简写 arr

说明:一组【有序】数据的集合

  1. 数组就是在内存中开辟出一块连续的空间
  2. 数组也是一个变量,可以存储一连串的变量/值
  3. 数组的大小可以动态的调整,并且没有长度的限制。
  4. 数组可以存储任意类型的数据。

数组的创建

数组的创建有两种形式:

1.构造函数创建

JS语言提供了一个构造函数:Array(),我我们可以通过该构造函数创建一个数组。(了解)

js
// 创建一个空数组,括号中没有值,表示创建的数组没有值 
var arr1 = new Array(); 
// 创建一个长度为5的数组,括号中只有一个数字,表示创建的数组的长度 
var arr2 = new Array(5); 
// 创建一个长度为1的数组,值为'a',括号中只有一个非数字的值,值表示的为数组的值 
var arr2 = new Array('a'); 
//创建一个包含4个元素的数组
var arr3 = new Array(13,43,2,120); 
//创建一个包含4个元素的数组 
var arr3 = new Array('a','x','z',120);

构造函数Array()其实对于我们的使用来说并不友好,因为同一个函数居然有两种行为。这种区别对于新手来说很容易产生混淆,所以我们一般不推荐使用构造函创建数组。

2.字面量创建

我们通常都是更加习惯使用字面量的形式创建数组。 直接使用中括号**"[ ]"**创建即可。

js
// 创建一个空数组 
var nums = []; 
//创建一个包含4个元素的数组 
var nums = [13,43,2,120]; 
//创建一个包含4个元素的数组 
var nums = [13,'abcd',true,120];

数组的索引(下标)

前面我们已经学习了对数组的创建,而我们想要访问数组中数据的话就需要:数组索引。 数组索引:对数组中的数据进行编号,从0开始,依次递增,我们可以通过对数组索引来访问数组中的元素。

js
// 创建数组 
var arr = []; 
// 为数组元素赋值, arr[索引]
arr[0] = 12;
arr[1] = 12.5; 
arr[2] = 'hello'; 
// 获取数组元素的值 
console.log(arr[0]);// 12
console.log(arr[1]);// 12.5 
console.log(arr[2]);// hello

上面的代码中我们从索引4直接跳到索引9,那么中间被落下的元素会怎么办呢? 如果数组中元素没有被赋值那么它会有一个默认值:undefined

数组的遍历

for循环遍历

js
var arr = [1,2,3]; 
for(var i=0;i<arr.length;i++){ 
    console.log(arr[i]);// 1,2,3
}

for...in循环

for...in中变量item就是数组的索引号

js
var arr = [1,2,3]; 

for( var item in arr ){ 
    console.log(item); // 0,1,2
    console.log(arr[item]);	// 1,2,3
}

for...of循环

for...in中变量item就是数组中的每一个值

js
const arr=[1,2,3]

for(let item of arr){
    console.log(item)  // 1,2,3
}

2.数组的属性

属性描述
constructor返回创建数组对象的原型函数。
length通过arr.length,设置或返回数组元素的个数
prototype允许你向数组对象添加属性或方法。

3.数组的原型方法

JS语言为我们提供了一些数组方法,,这些方法使得我们能够很方便的操作数组。

以下是常用的一些数组方法

push()

  • 作用:向数组末尾添加一个或多个数据
  • 返回值返回数组新的长度
  • 会改变原数组
js
var arr1 = [123,'abc','hello',true,456]; 
arr1.push("world"); 
console.log(arr1); // [123,'abc','hello',true,456,"world"]

var arr2 = [123,'abc','hello',true,456]; console.log(arr2.push("world",789)); // 7

pop()

  • 作用:删除数组的最后一个数据
  • 返回值:并返回被删除的数据
  • 会改变原数组
js
var arr1 = [123,'abc','hello',true,456];
arr1.pop(); console.log(arr1); // [123,'abc','hello',true] 

var arr2 = [123,'abc','hello',true,456]; console.log(arr2.pop()); // 456

unshift()

  • 作用:向数组的开头添加一个或多个数据
  • 返回值:并返回数组新的长度
  • 会改变原数组
js
var arr1 = [123,'abc','hello',true,456]; 
arr1.unshift('美丽',912); 
console.log(arr1); // ['美丽',912,123,'abc','hello',true,456] 

var arr2 = [123,'abc','hello',true,456]; 
console.log(arr2.unshift('美丽')); // 6

shift()

  • 作用:删除数组的第一个数据
  • 并返回被删除的数据
  • 会改变原数组
js
var arr1 = [123,'abc','hello',true,456]; arr1.shift(); 
console.log(arr1); // ['abc','hello',true,456] 

var arr2 = [123,'abc','hello',true,456]; 
console.log(arr2.shift()); // 123

sort()

  • 作用:默认按字符编码Asc的顺序排列(排列顺序可能会有问题),非string类型会自动转换为string,可自定义比较规则
  • 返回值排序后的数组
  • 会改变原数组
js
var numArr = [23,89,65,33,12,99]; 
console.log(numArr.sort());

升序排序

js
let arr=[5,2,3,1,5]
arr.sort((a,b)=>{
    return a-b
})
console.log(arr)  //[1, 2, 3, 5, 5]

降序排序

js
let arr=[5,2,3,1,5]
arr.sort((a,b)=>{
    return b-a
})
console.log(arr)  	//[5, 5, 3, 2, 1]

根据数组中指定键排序

js
const list = [
    {
        a: 1,
        b: 99,
    },
    {
        a: 2,
        b: 88,
    },
    {
        a: 3,
        b: 77,
    },
];
list.sort((a, b) => {
    return a.a - b.a ;        // 升序排序
    // return b.a - a.a;      // 降序排序
});
console.log(list);

toSorted()

sort()方法的复制版本,用法同sort(),不会改变原数组,返回一个新数组

reverse()

  • 作用:将数组元素反转排列
  • 返回值:反转后的数组
  • 会改变原数组
js
var arr = [34,'hello',187,'world','sss']; 
conso.log(arr.reverse()); // ['sss','world',187,'hello',34]

toReversed()

reverse()方法的复制版本,用法同reverse(),不会改变原数组,返回一个新数组

concat()

  • 作用:将多个数组拼接成一个数组
  • 返回值:拼接后的数组
  • 不会改变原数组
js
var arr1 = [1,2,3,4,5]; 
var arr2 = ['a','b','c','d','e']; 

var arr3 = arr1.concat(arr2);
console.log(arr3); // [1,2,3,4,5,'a','b','c','d','e']

slice()

  • 作用:截取数组的元素(项)。对数组进行截取,通过传入索引(下标)来实现 截取
  • 返回值:被截取的新数组
  • 不会改变原数组

1.一个参数

  • 表示从这个索引位置开始(包含此索引位置) 一直截取到数组结束
js
var arr1 = [666,'老铁双击','hello','你好',false,'enne','哈哈哈',true];

console.log(arr1.slice(4)); // [false, 'enne', '哈哈哈', true]

2.两个参数

  • 第一个参数 表示 开始截取的索引位置(包含此索引位置)
  • 第二个参数 表示 结束截取的索引位置(不包含此索引位置)
js
console.log(arr1.slice(2,6)); // ['hello', '你好', false, 'enne']
console.log(arr1.slice(1,7)); // ['老铁双击', 'hello', '你好', false, 'enne', '哈哈哈']

3.第二个参数为负值

  • 此时,第一个参数仍为开始截取的索引
  • 第二个参数表示从后往前数第几个
  • 此刻数组最后一项为-1,依次往前推-2,-3
js
console.log(arr1.slice(3,-2)); // ['你好', false, 'enne']

console.log(arr1);// [666, '老铁双击', 'hello', '你好', false, 'enne', '哈哈哈', true]

splice()

  • 作用:向/从数组中删除项目,也可以用作替换操作
  • 返回值被删除的项目组成的新数组
  • 会改变原数组

一个参数

表示从这个索引位置开始删除(包含此索引位置),一直删除到数组结束

js
var arr1 = [12,24,36,47,58,69,70,81,92]; 

var arr2 = arr1.splice(3); 
console.log(arr1); // [12,24,36] 
console.log(arr2); // [47,58,69,70,81,92]

两个参数

  • 第一个参数表示开始删除的索引位置(包含此索引位置)
  • 第二个参数表示删除的元素/值的个数
js
var arr3 = [12,24,36,47,58,69,70,81,92]; 
var arr4 = arr1.splice(3,5);
console.log(arr3); // [12,24,36,92] 
console.log(arr4); // [47,58,69,70,81]

三个参数及以上

  • 从第三个参数(包括第三个)开始往后,都表示的是要替换被删除的值
js
var arr5 = [12,24,36,47,58,69,70,81,92]; 
var arr6 = arr1.splice(3,5,"a");
console.log(arr5); // [12,24,36,"a",92] 
console.log(arr6); // [47,58,69,70,81] 

var arr7 = [12,24,36,47,58,69,70,81,92];
var arr8 = arr7.splice(3,5,"a",'bb');
console.log(arr7); // [12,24,36,"a",'bb',92]
console.log(arr8); // [47,58,69,70,81]

toSpliced()

splice()方法的复制版本,用法同splice(),不会改变原数组,返回一个新数组

toString()

  • 作用:toString() 方法可把一个 Number 对象转换为一个字符串,将数组转换为字符串,并以,隔开
  • 返回值转换成字符串的结果
  • 不会改变原数组
js
var arr1 = [1,'a','2','cc',555]; 
var arr2 = arr1.toString(); 
console.log(arr1); // [1, "a", "2", "cc", 555] 
console.log(arr2); // 1,a,2,cc,555

join()

  • 作用:将数组的各项值拼接为字符串
  • 返回值:根据传入参数将数组元素拼接的字符串
  • 不会改变原数组

不传入参数:直接将数组转换成字符串,并以,隔开

js
var arr = [1, '2', 3, 'a',true] 

console.log(arr.join()); // 1,2,3,a,true

传入参数:会根据传入的参数将数组的每一项值进行拼接,传入的值就是拼接的字符

js
//传入空字符串
console.log(arr.join(''));  // 123atrue

//传入其他内容
console.log(arr.join(1));	// 112131a1true
console.log(arr.join('+')); //1+2+3+a+true
console.log(arr.join('你好')); // 1你好2你好3你好a你好true

forEach(fn)

作用:接收一个函数作为参数,对数组的每个数据执行一次给定的函数(和for循环类似)

没有返回值

不会改变原数组

语法arr.forEach((item,i,arr)=>{})

参数

  • 参数1:数组的各项值;
  • 参数2:各项值的下标;
  • 参数3:数组本身
js
var arr = [13,24,35,46];
arr.forEach(function(value,index,arr){ 
    console.log(value,index,arr); 
});

// 13 0 [ 13, 24, 35, 46 ]
// 24 1 [ 13, 24, 35, 46 ]
// 35 2 [ 13, 24, 35, 46 ]
// 46 3 [ 13, 24, 35, 46 ]

运用forEach()计算数组每一项和

js
const arr=[1,2,3,4,5]

let sum=0
arr.forEach((item,i)=>{
    sum+=item
})

console.log(sum)   // 15

filter(fn)

作用:参数为一个函数,过滤数组中符合条件的值

返回值返回一个新数组,把符合条件的值返回(push)到新数组中,新数组和原数组长度不一定相等

不会改变原数组

语法arr.filter((item,index,arr)=>{})

参数

  • 参数1:数组的值;
  • 参数2:值的下标;
  • 参数3:数组本身;
js
var arr1 = [13,24,35,46,57,68,79,80,91]; 
var arr2 = arr1.filter(function(value,index,arr){ 
    return (value>40); 
}); 
console.log(arr2); // [46,57,68,79,80,91]

map(fn)

  • 作用:通过指定函数执行数组中的每一项值 ,
  • 返回值返回新的数组,把经过操作的值返回(push)到新数组中
  • 不会改变原数组

数组中有几个值就遍历几次,新数组和原数组长度一定相等

js
var arr1 = [1,2,3,4,5]; 

var arr2 = arr1.map(function(value,index,arr){ 
    return value+1;
});
console.log(arr2); // [2,3,4,5,6]

var arr3 =arr1.map((item,index)=>{
    if(item>=3) return item
})
console.log(arr3); // [undefined,undefined,3,4,5]

indexOf()

  • 作用:传入的是具体数值,根据数值查找下标
  • 返回值:
    • 如果存在:返回数组中第一次出现的下标
    • 如果不存在:则返回**-1**。
  • 不会改变原数组
js
var arr1 = [1,2,3,3,3,4,5]; 
console.log(arr1.indexOf(3))  // 2

console.log(arr1.indexOf('55'))  // -1

lastIndexOf()

  • 作用:查找传入的值在数组中最后一次出现的下标
  • 返回值:返回查找值在数组中最后一次出现的下标,如果不存在查找值,则返回**-1**。
  • 不会改变原数组
js
var arr1 = [1,2,3,3,3,4,5]; 
console.log(arr1.lastIndexOf(3))  // 4

console.log(arr1.lastIndexOf('55'))  // -1

find()

返回值:返回数组中第一个符合条件的值。否则返回 undefined

不会改变原数组

语法

js
array.findIndex(function(item, index, arr), thisValue)

参数说明

参数描述
function(item, index,arr)必须。数组每个元素需要执行的函数。
thisValue可选。 传递给函数的值一般用 "this" 值。
参数描述
item必选。数组遍历的当前项
index可选。当前元素的索引
arr可选。当前元素所属的数组对象
js
const arr=[1,2,5,9,10]

const res=arr.find(item=>{
    return item>5
})

console.log(res)

findIndex()

作用:查找对应值的下标

语法array.findIndex(function(item, index, arr), thisValue)

返回值:返回符合条件的值第一次出现的下标

不会改变原数组

参数说明

参数描述
function(item, index,arr)必须。数组每个元素需要执行的函数。
thisValue可选。 传递给函数的值一般用 "this" 值。
参数描述
item必选。数组遍历的当前项
index可选。当前元素的索引
arr可选。当前元素所属的数组对象

reduce()

作用:计算数组各项之和

返回值:

不会改变原数组

语法:

js
arr.reduce((total, item, index, arr)=>{}, initialValue)

参数

  • 第一个参数:必选,用于执行每个数组元素的函数。
    • 第一个参数:初始值,或者计算结束后的返回值
    • 第二个参数:数组当前项
    • 第三个参数:当前项下表
    • 第四个参数:原数组
  • 第二个参数:可选,初始值

计算数组各项之和

js
const arr=[1,2,3,4,5]

let sum=arr.reduce((total, item, i, arr)=>{
    return total+=item
}, 10)

console.log(sum)

some()

作用:判断数组中是否符合条件的值

返回值:若数组中有符合条件的值,返回true,否则返回false

不会改变原数组

参数

  • 参数1:数组的各项值;
  • 参数2:各项值的下标;
  • 参数3:数组本身
js
const arr=[1,2,3,4,5]

const res=arr.some((item,index)=>{
    return item>3
})

console.log(res)	// true

every()

作用:判断数组中是否全部符合条件的值

返回值:若数组中有符合条件的值,返回true,否则返回false

不会改变原数组

参数

  • 参数1:数组的各项值;
  • 参数2:各项值的下标;
  • 参数3:数组本身
js
const arr=[1,2,3,4,5]

const res=arr.every((item,index)=>{
    return item<6
})

console.log(res)	// flase

fill()

作用:将一个固定值替换数组的元素。

会改变原数组

语法

js
array.fill(value, start, end)

参数

  • value:必须,填充的值
  • start:可选,开始填充的下标,包括此下标,默认为0
  • end:可选,停止填充下标,不包括此下标,默认为数组的长度
js
const arr=[1,2,3,4,5,6,7,8,9]
arr.fill('a',2,6)
console.log(arr) // [1,2,'a','a','a','a',7,8,9]

若只写第一个参数,则会将数组中所有值都替换

js
const arr=[1,2,3,4,5,6]
arr.fill(5)
// 相当于  arr.fill('a',0,arr.length)
console.log(arr) // 5,5,5,5,5,5

4.数组的静态方法

Array.isArray()

判断一个变量是否为数组,返回布尔值

js
var a=12
console.log(Array.isArray(a))  // false

var arr=[1,2]
console.log(Array.isArray(arr))	 // true

Array.form()

作用:from() 方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。

返回值:如果对象是数组返回 true,否则返回 false。

语法

js
Array.from(arrayLike, mapFn, thisArg)

参数

  • arrayLike:想要转换成数组的类数组或可迭代对象。
  • mapFn(item,index):可选,可以通过此回调遍历arrayLike,并返回经过操作的值
    • item:数组当前正在处理的元素。
    • index:数组当前正在处理的元素的索引。
  • thisArg:可选,执行 mapFn 时用作 this 的值。

字符串转数组

js
var arr = Array.from("Hello");
console.log(arr)  //  [ 'H', 'e', 'l', 'l', 'o' ]

set数据解构转数组

js
var setObj = new Set(["a", "b", "c"]);
var objArr = Array.from(setObj);

console.log(objArr)  // ["a", "b", "c"]

使用回调函数

js
var arr = Array.from([1,2,3],(item,index)=>{
    return item+index
});

console.log(arr)  // [ 1, 3, 5 ]

5.数组的常见算法

数组是JS中最常使用的数据集合之一,所以对它的操作可谓是千奇百怪,有一些操作因为它们的实用性和简易性得到程序员的认可,我们把这些操作叫做数组的算法。

  • 常见的数组算法:冒泡排序选择排序数组去重

冒泡排序

冒泡,是因为越大的元素会经由交换慢慢“浮”到数列的顶端,就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

  • 那冒泡排序是怎么样式的执行过程呢?接下来看一下: (将大的值冒泡到最后)
js
var arr = [83,46,17,68,27,99,5]; // 数组 
//第一次冒泡 6 
// 83 , 46 , 17 , 68 , 27 , 99 , 5 第一个 和 第二个 比 结果 变 
// 46 , 83 , 17 , 68 , 27 , 99 , 5 第二个 和 第三个 比 结果 变 
// 46 , 17 , 83 , 68 , 27 , 99 , 5 第三个 和 第四个 比 结果 变 
// 46 , 17 , 68 , 83 , 27 , 99 , 5 第四个 和 第五个 比 结果 变 
// 46 , 17 , 68 , 27 , 83 , 99 , 5 第五个 和 第六个 比 结果 不变
// 46 , 17 , 68 , 27 , 83 , 99 , 5 第六个 和 第七个 比 结果 变 
// 46 , 17 , 68 , 27 , 83 , 5 , 99 结束(最大的值已到最后) 

//第二次冒泡 5 
// 46 , 17 , 68 , 27 , 83 , 5 , 99 第一个 和 第二个 比 结果 变 
// 17 , 46 , 68 , 27 , 83 , 5 , 99 第二个 和 第三个 比 结果 不变
// 17 , 46 , 68 , 27 , 83 , 5 , 99 第三个 和 第四个 比 结果 变 
// 17 , 46 , 27 , 68 , 83 , 5 , 99 第四个 和 第五个 比 结果 不变
// 17 , 46 , 27 , 68 , 83 , 5 , 99 第五个 和 第六个 比 结果 变 
// 17 , 46 , 27 , 68 , 5 , 83 , 99 结束(第二大的值已到到倒数第二的位置) 

//第三次冒泡 4 
// 17 , 46 , 27 , 68 , 5 , 83 , 99 第一个 和 第二个 比 结果 不变 
// 17 , 46 , 27 , 68 , 5 , 83 , 99 第二个 和 第三个 比 结果 变 
// 17 , 27 , 46 , 68 , 5 , 83 , 99 第三个 和 第四个 比 结果 不变
// 17 , 27 , 46 , 68 , 5 , 83 , 99 第四个 和 第五个 比 结果 变 
// 17 , 27 , 46 , 5 , 68 , 83 , 99 结束(第三大的值已到到倒数第三的位置)

//第四次冒泡 3 
// 17 , 27 , 46 , 5 , 68 , 83 , 99 第一个 和 第二个 比 结果 不变 
// ...... 
//第五次冒泡 2 
//第六次冒泡 1
js
var arr = [83,46,17,68,27,99,5]; 
var temp; 
for(var i=0;i<arr.length-1;i++){ 
    for(var j=0;j<arr.length-1-i;j++){ 
        if(arr[j]>arr[j+1]){ 
            temp = arr[j]; 
            arr[j]=arr[j+1];
            arr[j+1]=temp;
        }
    } 
} 
console.log(arr)

选择排序

首先从原始数组中找到最小的元素,并把该元素放在数组的最前面,然后再从剩下的元素中寻找最小的元素,放在之前最小元素的后面,直到排序完毕。

js
var arr = [83,46,17,68,27,99,5]; 
var temp;
var minIndex; 
for(var i=0;i<arr.length-1;i++){ 
    minIndex=i; 
    for(var j=i+1;j<arr.length;j++){ 
        if(arr[j]<arr[minIndex]){
            minIndex=j; }
    }
    temp=arr[i];
    arr[i]=arr[minIndex];
    arr[minIndex]=temp;
}
console.log(arr)

数组去重

程序可能会需要一个元素值相对唯一的数组,这样我们就需要将数组中重复的值剔除出去。

js
var arr = [11,2,2,2,'hello','world','hello']; 
var newArr = [];
for(var i=0;i<arr.length;i++){ 
    if(newArr.indexOf(arr[i])==-1){ 
        newArr.push(arr[i]);
    }
} 
console.log(newArr);

6.二维数组

概念

二维数组:就是数组的元素也是另一个完整的数组,数组就是作为另一个数组的元素存在的,在JS中其实本质上是不支持二维数组的,但是因为语法的松散性我却是可以实现二维数组的,乃至多维数组。

语法

定义二维数组

js
var arr = [ 
    [1001,'tom','jack','chris'], 
    [1002,'apple','orange','tomato'], 
    [1003,'HTML','CSS','JS'],
];

操作:第一个中括号代表操作的是一维、第二个中括号代表操作的二维

js
arr[2][3]; arr // 这个数组 
[2] // 一维中下标为2的值 
[3] // 二维中下标为3个值

遍历二维数组

遍历二维数组我们需要使用之前学过的双重循环来做最为合适,使用外层循环获得每一个二维数组,使用内存循环获得每一个二维数组里面的元素。

js
for(var i=0;i<arr.length;i++){ 
    for( var k=0;k<arr[i].length;k++ ){
        console.log(arr[i][k]);
    } 
}

7.伪数组

JavaScript中存在一种伪数组,可以使用数组的属性,但不能使用数组的方法

经常见到的伪数组有函数的arguments对象、dom.querySelectorAll获取的节点数组

arguments

在函数被调用时,在函数内部产生,用来接收函数的实参

  • 会将函数的所有实参,以数组的形式接收
  • arguments对象 是一个 以数组的形式存在的对象,并不是真正的数组,它是一个对象
js
function addsum() {
    console.log(arguments); 
    // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6 }
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);   // 1,2,3,4,5,6
    }
}
addsum(1, 2, 3, 4, 5, 6);

MIT Licensed