ES6|数组的扩展

类数组/伪数组

在 JavaScript 的世界里有些对象被理解为数组比如函数中的 arguments、DOM中的 NodeList等。当然,还有一些可遍历的对象,看上去都像数组却不能直接使用数组的 API,因为它们是伪数组(Array-Like),下面根据例子来理解伪数组与数组的区别:

伪数组具备两个特征:1. 按索引方式储存数据 2. 具有length属性
常见伪数组如下(此处定义的伪数组在后文伪数组转换成数组时会用到):

//使用instanceof来检测某个对象是否是数组的实例
//HTMLCollection是伪数组
let divs=document.getElementsByTagName('div')
console.log(divs)//HTMLCollection
console.log(divs instanceof Array)//false

let divs2=document.getElementsByClassName('xxx')
console.log(divs2)//HTMLCollection
console.log(divs2 instanceof Array)//false


//NodeList是伪数组
//querySelectorAll() 方法返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象。
let divs3=document.querySelectorAll('.xxx')
console.log(divs3)//NodeList
console.log(divs3 instanceof Array)//false


//arguments是伪数组
function foo(){
    console.log(arguments)//1 mooc true
    console.log(arguments instanceof Array)//false 
}
foo(1,'mooc',true)


//该对象是伪数组
let arrayList={
    0:"es6",
    1:"es7",
    2:"es8",
    length:3
}
console.log(arrayList)//{0: "es6", 1: "es7", 2: "es8", length: 3}
console.log(arrayList instanceof Array)//false

伪数组不具备数组的方法

//arr.push()方法是向数组尾部添加项
divs.push('div')//会报错
divs3.push('span')//会报错
arrayList.push('es9')//会报错

Array.from()将伪数组转换成数组

上面介绍了伪数组的各种特点,但是有时候我们希望伪数组可以使用数组的API时,就需要将伪数组转换成数组。ES5的做法是:

let args = [].slice.call(arguments)
let imgs =[].slice.call(document.querySelectorAll('img'))

基本原理是使用 call 将数组的 api 应用在新的对象上,换句话说是利用改变函数的上下文来间接使用数组的 api。在 ES6 中提供了新的 api 来解决这个问题,就是 Array.from(),代码如下:

let args = Array.from(arguments)
let imgs = Array.from(document.querySelectorAll('img'))

除此之外,Array.from()还有另外的用法,先来看看Array.from()的几个参数,Array.from(object, mapFunction, thisValue)

参数描述
object必需,要转换为数组的对象。
mapFunction可选,数组中每个元素要调用的函数。
thisValue可选,映射函数(mapFunction)中的 this 对象。

看了这几个参数至少能看到 Array.from() 还具备 map() 的功能:

var arr = Array.from([1, 2, 3], x => x * 10)
// arr[0] == 10
// arr[1] == 20
// arr[2] == 30

再比如我们想初始化一个长度为 5 的数组,每个数组元素默认为 1,之前的做法是这样的:

let arr = Array(6).join(' ').split('').map(item => 1)
console.log(arr)//[1,1,1,1,1]
let arr=Array.from({
    length: 5
}, ()=>1)
console.log(arr)//[1,1,1,1,1]

Array.of()构造数组

构造数组的两种方式:
1、Array 构造函数构造数组

//new Array()
let arr=new Array(1,2)
console.log(arr)//[1,2]

let arr2=new Array(3)
console.log(arr2)//[empty*3]

let arr3=new Array(1,true,'hello',[1,2,3],{
         name:'wdl'
})
console.log(arr3)//[1, true, "hello", Array(3), {name:'wdl'}]

2、Array.of()构造数组
*创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型
*与Array 构造函数之间的区别在于处理整数参数:Array.of(3) 创建一个具有单个元素 3 的数组,而 Array(3) 创建一个长度为3的空数组

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

let arr2=Array.of(3)
console.log(arr2)//[3]

let arr=Array.of(1,true,'hello',[1,2,3],{
    name:'wdl'
})
console.log(arr)//[1, true, "hello", Array(3), {name:'wdl'}]

Array.prototype.copyWithin()数组浅拷贝

Array.prototype.copyWithin(target,start,end)

参数描述
target复制序列到该位置
start开始复制元素的起始位置,如果 start 被忽略,copyWithin 将会从0开始复制。
end开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。

*浅复制数组的一部分到同一数组中的另一个位置,并返回它,改变原数组但不改变原数组的长度

//copyWithin()
let arr=[1,2,3,4,5]
console.log(arr.copyWithin(1,3))//[1,4,5,4,5]
console.log(arr)//[1,4,5,4,5]

Array.prototype.fill()数组填充

Array.prototype.fill(value,start,end)

参数描述
value必需。用来填充数组元素的值。
start可选。起始索引,默认值为0。
end可选。终止索引,默认值为 this.length。

*改变原数组,返回修改过的数组

let arr1=new Array(3).fill(7)
console.log(arr1)//[7,7,7]

let arr2=[1,2,3,4,5]
arr2.fill('hello',1,3)
console.log(arr2)//[1, "hello", "hello", 4, 5]

Array.prototype.includes()判断一个数组是否包含一个指定的值

*与indexOf()区别:
indexOf返回数组下标,includes()返回布尔值
indexOf无法检验NaN,includes()可以

let arr=[1,2,3,NaN]
console.log(arr.indexOf(NaN))//-1
console.log(arr.includes(NaN))//true
console.log(NaN==NaN)//false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值