Array
-
创建数组的方法:
- new Array 或者 Array() 效果一样
- Object()
- 字面量
-
跟其他语言中的数组一样,Array也是一组有序的数据,不同的是,数组中每个槽位可以存储任意类型的数据;数组也是动态大小的,会随着数据添加而自动增长。
-
数组内存地址本质上不是连续的(
ArrayBuffer
会分配连续空间)- 但只要数组里存的是相同类型的值,在内存中的地址还是连续的。
-
push/pop
方法运行的比较快,而shift/unshift
比较慢。 -
数组的原型对象(prototype)的数据类型也是数组
-
数组默认按照字典序比较大小
-
如果数组中某一项是 null 或 undefined ,则在 join() 、 toLocaleString() 、toString() 和 valueOf() 返回的结果中会以空字符串表示。
-
ECMAScript 提供了 3 个严格相等的搜索方法: indexOf() 、 lastIndexOf() 和 includes()
-
Array.isArray()
:判断是否为数组 -
Array.from
:将类数组或可迭代的对象转为数组,并返回- 浅拷贝
- 函数:类似map、foreach的函数,参数为item
Array.from(arrayLike,callback, this)
Array()的坑
Array() // []
Array(3) // [, , ,] 出现歧义
Array("Greg"); //['Greg']
Array(3, 11, 8) // [3, 11, 8]
- 只传入一个参数时,如果这个值是数值,则会创建一个长度为指定数值的数组;而如果这个值是其他类型的,则会创建一个只包含该特定值的数组。
解决
Array.of()
:将参数,转换为数组(用于替代Array()
)
空位
-
忽略空位:
forEach()
filter()
reduce()
every()
some()
-
不会忽略空位:
length
map()
for...of
方法
不改变数组 | 改变数组 |
---|---|
join() | unshift() , shift() |
concat() | push() , pop() |
slice() | reverse() |
map() , foreach() , filter() | splice() |
some() , every() | sort() |
reduce() , reduceRight() | copyWithin() |
indexOf() , lastIndexOf() | fill() |
find(),findIndex() | |
entries(),keys() ,values() | |
includes() | |
flat() |
方法 | 作用 | 返回值 |
---|---|---|
join() | 字符串连接 | 字符串 |
concat() | 数组合并 | 新数组 |
slice() | 数组截取(浅拷贝) | 新数组 |
indexOf(item, from) | 获取元素在数组中第一次出现的下标 | 下标|-1 |
includes(item, from) | 判断数组是否包含给定的值 | 布尔值 |
flat() | 扁平化数组 | 新数组 |
unshift() , shift() | 在数组的顶端增加(多个元素)|删除元素 | length|删除元素 |
push() , pop() | 在数组的末端增加(多个元素)|删除元素 | length|删除元素 |
reverse() | 颠倒数组 | 更改后的原数组 |
splice() | 添加,删除和插入数组成员 | 被删除元素 |
sort() | 按照首字母的Unicode 进行排序 | 更改后的原数组 |
fill(填充值,start,end) | 填充数组 | 更改后的原数组 |
copyWithin(插入,start,end) | 区域复制并覆盖 | 更改后的原数组 |
遍历数组 | 作用 | 返回值 |
---|---|---|
map | 根据return设置元素 | 新数组 |
foreach | 纯遍历 | 无 |
filter | return后为条件,返回满足的元素数组 | 新数组 |
reduce | 根据return的公式进行累计 | 累计后的值 |
some | return后为条件,满足一个则返回true | 布尔值 |
every | return后为条件,所有满足才返回true | 布尔值 |
find | return后为条件,返回满足的元素第一个元素值 | 数组元素 |
findIndex | 匹配值 | 数组元素下标 |
entries(),keys() ,values() | 遍历键值对,键名,键值 | 遍历器 |
Array.prototype.splice(start, deleteCount, …)
-
参数1:起始下标
-
参数2:删除个数,为0,则代表插入|增加
-
之后的参数:插入元素
-
允许负索引
Array.prototype.slice(start, end)
- 范围:[start,end)
- 提取为新数组(浅拷贝)
- 无参时,提取整个内容
- 只有一个参数时,范围默认到末尾处
- 允许负索引
Array.prototype.join()
-
如果不提供参数,默认用逗号分隔
-
如果数组成员是
undefined
、null
、空位
,会被看作空字符串
includes()、indexOf()、 lastIndexOf()
- 内部都使用了
===
- indexOf() 和 lastIndexOf() 都返回要查找的元素在数组中的位置,如果没找到则返回-1。
includes() 返回布尔值 - 但是includes能识别NaN
includes('')
返回0
Array.prototype.sort(callback)
- 升序:a-b
- 降序:b-a
- 默认按照首字母的
Unicode
进行排序
copyWithin(插入,start,end)
- 一个参数时:复制所有,插入到参数位置
- 两个参数时,第一个是插入位置,第二个是复制起始
map(),foreach()
-
内部原理:相当于每一个回调函数都被包装为立即执行函数,同时执行,所以:
- 遍历范围在调用之前就已经确定
- 没有办法跳出
-
所以对原数组进行增加操作时,新增的数据不会在本次循环展示,因为范围已经固定了。
-
进行删除操作时,如果更改了属于范围内的数据,那当然能看到了
reduce()
- 如果为空数组则报错
- 第三个参数为初始值(不是this)
- 第三个参数默认为数组第一个值
数组去重的方法
- Set
- 双重for循环+splice
- includes|indexOf和数组遍历方法搭配
- Map用has去判断
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
Set数组
{}
!=={}
const set=new Set(arr);
const new_arr=[...set]
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
双层for循环
{}
!=={}
- NaN!==NaN
let len = arr.length
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
len-- // 减少循环次数提高性能
j-- // 保证j的值自加后不变
}
}
}
console.log(arr);
//[1,'true',true,15,false,undefined,null,NaN,NaN,'NaN',0,'a',{},{}]
forEach+indexOf
{}
!=={}
- NaN!==NaN
let new_arr=[]
arr.forEach((item)=>{
if(new_arr.indexOf(item)===-1){
//没有
new_arr.push(item)
}
})
console.log(new_arr);
//[1,'true',true,15,false,undefined,null,NaN,NaN,'NaN',0,'a',{},{}]
forEach+includes
{}
!=={}
let new_arr=[]
arr.forEach((item)=>{
if(!new_arr.includes(item)){
//没有
new_arr.push(item)
}
})
console.log(new_arr);
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
filter+indexOf
{}
!=={}
- 因为indexOf不认NaN,所以返回-1,所以一个都不符合当前index
let new_arr = arr.filter((item, index) => {
return arr.indexOf(item, 0) === index//如果是第一个元素
})
console.log(new_arr);
//[1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {}, {}]
reduce+includes
let new_arr=arr.reduce((pre,item)=>{
return pre.includes(item)?pre:[...pre,item]
},[])
console.log(new_arr);
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
Map
let m = new Map()
let rs=[]
arr.forEach((item, index) => {
m.set(item,index)
})
for(let i of m){
rs.push(i[0])
}
console.log(rs);
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
【1】
var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
//[]
- filter过滤空位
【2】
var a = [1, 2, 3, 1, 2, 3];
a.forEach((item, index,arr) => {
console.log(index, item,arr);
if (item === 1) {
a.splice(index, 1);
}
});
//0 1 [ 1, 2, 3, 1, 2, 3 ]
//1 3 [ 2, 3, 1, 2, 3 ]
//2 1 [ 2, 3, 1, 2, 3 ]
//3 3 [ 2, 3, 2, 3 ]
- 对于增加|删除操作,所显示的值或索引,根据当前更改后的数组而定
【3】
var arr = Array(3);
let rs=arr.map(function(elem) { return '1'; });
console.log(rs);
//[undefined,undefined,undefined]
- Array函数的缺陷
【4】
Array.isArray( Array.prototype )
//true
- 数组的原型对象的数据类型是数组
【5】
[,,,].join(", ")
//", , "
-
js在定义数组的时候允许最后一个元素后跟一个
,
[,].length为3
【6】
var a = [1, 2, 3],
b = [1, 2, 3],
c = [1, 2, 4]
a == b
a === b
a > c
a < c
//false, false, false, true
- 数组按照字典序比较大小