《红宝书》 |Array数组介绍及用法
ECMAScript的
Array
数组中每个槽位可以储存任意类型的数据。
基本概念
创建数组
通过Array
构造函数创建
let colors=new Array()
let colors=new Array(10) //可传入数值 表示数组中元素的数量
let colors=new Array("red","green","yellow") //可传入保存的元素
通过字面量创建
let colors=[]
let colors=["red","green","yellow"]
数组空位
可以使用一串逗号来创建空位。
let arr=[,,,,,]
ES6新增方法普遍将空位当做存在的元素,值为undefined
索引与length
要取得或设置数组的值,需要使用中括号与元素相应的位置索引:
let colors=["red","green","yellow"]
console.log(colors[0]) //显示第一项
colors[2]="blue" //修改第三项
colors[3]="orange" //增加第四项
length
是数组的属性,表示数组的元素数目。通过修改length
可以对数组进行删除或增加元素的操作:
let colors=["red","green","yellow"]
colors.length=2 //删除
console.log(colors[2]) //undefined
colors.length=4 //添加,新元素以undefined填充
数组最后一个元素的索引始终是length-1
,而使用length
可以方便地向末尾添加新元素:
let colors=["red","green","yellow"]
colors[colors.length]="blue"
colors[colors.length]="black"
检测数组
在只有一个全局作用域的情况下,可以使用instanceof
:
let something=[1,2]
console.log(something instanceof Array)
如果页面有多个全局执行上下文,就会有不同版本的Array构造函数。使用Array.isArray()
就可以不用考虑这些问题:
let something=[1,2]
console.log(Array.isArray(something))
转换
转换成数组
Array.from()
用于将类数组结构转换为数组实例Array.from("Matt") //["M","a","t","t"] //可接受第二个参数,对转换后的数组进行操作 Array.from([1,2,3],x=>x**2) //[1,4,9]
类数组结构:任何可迭代的结构;或有一个length属性和可可索引元素的结构
Array.of()
用于将一组参数转换为数组实例Array.of(1,2,3,4) //[1,2,3,4]
转换成字符串
toString()
(不改变原数组)toLocaleString()
(不改变原数组)join(分割符)
:默认用,
将元素分隔开。(不改变原数组)let arr=["red","green","yellow"] arr.toString() //red,green,yellow arr.toLocaleString() //red,green,yellow arr.join() //red,green,yellow arr.join("||") //red||green||yellow
如果数组中某一项是null或undefined,这些方法返回的结果会以空字符串表示
实例方法
添加与删除元素
-
push(元素)
:将元素添加到数组末尾 -
unshift(元素)
:将元素添加到数组开头 -
pop()
:删除数组最后一项,返回被删除的元素 -
shift()
:删除数组开头一项,返回被删除的元素let colors=new Array() colors.push("red") //打印colors:["red"] colors.push("blue") //打印colors:["red","blue"] colors.unshift("green") //打印colors:["green","red","blue"] colors.pop() //打印colors:["green","red"] colors.shift() //打印colors:["red"]
操作数组
-
concat(元素|数组)
:可接受元素或数组,将其拼接在数组末尾。(不改变原数组)let colors=["red","green","yellow"] colors.concat("black",["pink","orange"]) //["red","green","yellow","black","pink","orange"]
-
slice(开始索引,结束索引)
:从开始位置到结束位置抽取元素组成新数组。(不改变原数组)let colors=["red","green","yellow","black"] colors.slice(1) //["green","yellow","black"] 没有结束索引时截取到结尾 colors.slice(1,3) //["green","yellow"]
-
splice(开始索引,要移除的个数,元素)
:可对数组进行删除、插入和替换三种操作。//删除:需要传入第一、二个参数 let colors=["red","green","yellow","black"] colors.splice(1, 1) //打印colors:["red","yellow","black"] //替换:需要传入第一、二、三个参数。其中第二个参数的数字与元素的个数应相对应 let colors=["red","green","yellow","black"] colors.splice(1, 1,"pink") //替换-打印colors:["red","pink","yellow","black"] //添加:需要传入第一、二、三个参数。其中第二个参数的数字为0 colors.splice(1, 0,"pink") //添加-打印colors:["red","pink","green","yellow","black"]
排序方法
reverse()
:反向排序let arr=[1,2,3,4,5] arr.reverse() //打印arr:[5,4,3,2,1]
sort()
:默认按照升序排序。即最小在前,最大在后。sort会在每一项调用String()
转型函数,然后再比较字符串。
由于let arr=[2,10,9,5] arr.sort() //打印arr:[10,2,5,9]
sort()
是按照字符串排序的,所以在很多情况是不适用的。为此,sort()
可以接受一个比较函数,用于判断哪个值应该排在前面。比较函数接受两个参数,如果第一个参数应该排在前面,就返回负值;如果相等,就返回0,如果第一个参数应该排在第二个参数的后面,就返回正值。下面是一个比较函数:
上面例子可简写成:function compare(value1,value2){ if(value1<value2){ return -1 }else if(value1>value2){ return 1 }else{ return 0 } } let arr=[2,10,9,5] arr.sort(compare) //打印arr:[2,5,9,10]
let arr=[2,10,9,5] arr.sort((a,b)=>a<b?1:a>b?-1:0) //打印arr:[2,5,9,10] arr.sort((a,b)=>a-b) //打印arr:[2,5,9,10]
搜索方法
-
indexOf(元素,开始索引)
:从前面搜索,返回该元素索引位置,找不到则返回-1 -
lastIndexOf(元素,开始索引)
:从后面搜索,返回该元素索引位置,找不到则返回-1 -
includes(元素,开始索引)
:从前面搜索,如果找得到返回true,否则falselet num=[1,2,3,4,5,4,3,2,1] num.indexOf(4) //3 num.lastIndexOf(4) //5 num.includes(4) //true num.indexOf(4,4) //5 num.lastIndexOf(4,4) //3 num.includes(4,7) //false
以上三种方法在比较参数与数组每一项的元素时,采取的是严格相等模式,即
===
-
find(函数)
:返回第一个匹配的元素(不改变原数组) -
findIndex(函数)
:返回第一个匹配元素的索引。找不到则返回-1let people=[ {name:"小明",age:17}, {name:"李华",age:27}, ] let result=people.find(item=>item.age>18) //{"name":"李华","age":27} let result2=people.findIndex(item=>item.age>18) //1
传入的函数接受3个参数:元素、索引、数组本身。断言函数的返回值为true时被认为是匹配
迭代器方法
在ES6中,Array的原型暴露了三个用于检索数组内容的方法:
keys()
:返回数组索引的迭代器values()
:返回数组元素的迭代器entries()
:返回数组键值对的迭代器let arr=["red","green","yellow","blue"] Array.from(arr.keys()) //[0,1,2,3] Array.from(arr.values()) //["red","green","yellow","blue"] Array.from(arr.entries()) //[[0,"red"],[1,"green"],[2,"yellow"],[3,"blue"]]
迭代方法
-
every(函数,作用域对象)
:对数组每一项都运行函数,如果每一项都返回true,则该方法返回true -
some(函数,作用域对象)
:对数组每一项都运行函数,如果有一项返回true,则该方法返回true -
filter(函数,作用域对象)
:对数组每一项都运行函数,将返回true的项组成新数组并返回(不改变原数组) -
map(函数,作用域对象)
:对数组每一项都运行函数,返回调用函数后的新数组(不改变原数组) -
forEach(函数,作用域对象)
:对数组每一项都运行函数,没有返回值。本质上相当于for循环遍历(不改变原数组)传入的函数接受3个参数:元素、索引、数组本身
let num=[1,2,3,4,5,4,3,2,1] num.every(item=>item>2) //false num.some(item=>item>2) //true num.filter(item=>item>2) //[3,4,5,4,3] num.forEach(item=>操作)
归并方法
reduce(函数,归并起点)
:从前面开始往后面迭代所有项,并在此基础上构建一个最终返回值reduceRight(函数,归并起点)
:从后面开始往前面迭代所有项,并在此基础上构建一个最终返回值传入的函数接受4个参数:上一个归并值、当前项、当前项索引、数组本身。这个函数返回的任何值都会成为下一次调用的第一个参数。
let num=[1,2,3,4,5] let result=num.reduce((prev,cur,index,array)=>{ return prev+cur }) console.log(result) //15
复制与填充
fill(填充内容,开始索引,结束索引)
:在给定的索引范围中,填充内容覆盖原始内容let arr=[0,0,0,0,0] arr.fill(5) //打印arr:[5,5,5,5,5] arr.fill(5,3) //打印arr:[0,0,0,5,5] arr.fill(5,1,3) //打印arr:[0,5,5,0,0] arr.fill(5,3,10) //打印arr:[0,0,0,5,5] 仅填充存在部分,不会扩张 arr.fill(5,10,15) //打印arr:[0,0,0,0,0] 超出数组边界,忽略 arr.fill(5,4,2) //打印arr:[0,0,0,0,0] 方向相反,忽略
copyWithin(覆盖索引,开始索引,结束索引)
:先复制给定索引范围内原数组的元素,再将复制内容从覆盖索引开始覆盖let arr=[0,1,2,3,4,5,6,7,8,9] arr.copyWithin(5) //打印arr:[0,1,2,3,4,0,1,2,3,4] 没有开始索引时表示从索引0开始到结尾 arr.copyWithin(0,5) //打印arr:[5,6,7,8,9,5,6,7,8,9] arr.copyWithin(4,0,3) //打印arr:[0,1,2,3,0,1,2,7,8,9] arr.copyWithin(4,12,15) //打印arr:[0,1,2,3,4,5,6,7,8,9] 超出边界,忽略 arr.copyWithin(4,4,2) //打印arr:[0,1,2,3,4,5,6,7,8,9] 方向相反,忽略 arr.copyWithin(4,7,12) //打印arr:[0,1,2,3,7,8,9,7,8,9] 仅复制存在部分
使用该方式不能缩放原数组。对于参数,如果有开始索引和结束索引,表示从开始索引开始,到结束索引之前(即不包含结束索引)