目录
1.伪数组
1.什么叫做伪数组
- 伪数组的本质是一个对象,具有以下特点;
-
[1]按照索引的方式存储数据;
-
[2]具有length属性;
-
但是伪数组元素添加/删除时,length属性值不会随之改变
-
const likeArr = { 0:'chaochao', 1:18, 2:'女', legth:3 } delete likeArr[2] console.log('likeArr', likeArr )
-
-
发现删除了第三个元素,但是length值还是最初设置的3
-
-
[3]没有像pop,push,splice等内置的数组方法;
-
原因是->内置数组方法是在Array构造函数的原型对象(Array.prototype)上的,而伪数组的本质是一个对象,其构造函数指向的是Object!
-
-
-
2.将伪数组转化为真数组
1.Array.from(value)
- Array.from是es6新增的数组方法,用于将伪数组、Set、Map转为真正的数组;
- 不会改变原数据,返回一个标准数组;
// es6数组新方法 Array.form(伪数组),将伪数组转化为真数组
<script>
let arrayLike = {
0: 'tom',
1: '65',
2: '男',
3: '["janw","aa"]',
length: 4
}
console.log(arrayLike)//Object
let arr = Array.from(arrayLike)
console.log(arr)//Array
</script>
2.修改原型对象
[1]通过slice去修改原型对象
// slice方法若是没有传入参数,返回的是调用该方法的原数组;
// Array.prototype.slice() 返回一个空数组(原因并不是数组调用的)
// 此时修改this指向,相当于是伪数组调用,就会返回一个具有伪数组元素的真数组;
<script>
// 伪数组
let arrayLike = {
0: 'tom',
1: '65',
2: '男',
3: '["janw","aa"]',
length: 4
}
let trueArray = Array.prototype.slice.apply(arrayLike)
console.log(trueArray); //array
// 注:arrayLike还是一个对象
</script>
[2]直接修改原型对象-替换原型式继承
const obj = {
0:'chaochao',
1:18,
2:'女',
length:3
}
obj.__proto__ = Array.prototype
console.log( obj , obj.shift() )
可以看到我们将伪数组的原型对象直接改为Array构造函数的原型对象,此时伪数组变为数组、length也会随着元素数量而变化、也可以使用数组的内置方法了;
3.遍历
<script>
// 伪数组
let arrayLike = {
0: 'tom',
1: '65',
2: '男',
3: '["janw","aa"]',
length: 4
}
// 真数组
let array = []
for (let i = 0; i < arrayLike.length; i++) {
array.push(arrayLike[i])
}
console.log(array) //array
</script>
2.数组
1.概念
-
数组是值的有序集合;
-
每个值叫做一个元素;
-
每个元素在数组中有一个位置,以数字表示,称为索引;
-
-
数组是无类型的;
-
数组中的元素可以是任意类型;
-
不同元素的类型也可有所不同;
-
-
数组是动态的;
-
在创建数组时无须声明一个固定大小空间进行存储;
-
在数组长度变化时无须重新分配空间;
-
-
数组可能是稀疏的;
-
数组元素的索引不一定是连续的,他们之间可以有空缺;
-
2.创建数组
[1]使用字面量创建数组
-
空数组
-
const arr = []
-
-
带有元素的数组
-
const arr = [1,true,function(){}]
-
数组元素可以是任意数据类型
-
[2]使用构造函数创建数组
使用系统内置的构造函数Array来创建数组
-
语法
-
const arr = new Array(value)
-
value为可选参数
-
若是没有参数,创建一个空数组;
-
若是仅一个参数且为数字,表示数组长度,否则表示数组元素;
-
-
-
举例说明
-
const arr = new Array() console.log('arr', arr)
-
const arr = new Array(10) console.log('arr', arr)
-
const arr = new Array('10') console.log('arr', arr)
-
const arr = new Array(10, 20) console.log('arr', arr)
-
3.数组遍历
[1]for in 与 for of
[2]es6新增的数组遍历
4.常用的数组方法
1.用于连接两个或者多个数组
[1]使用concat方法将两个或多个数组合并为1个数组
- 作用:
将两个或多个数组中的元素添加到一个新的数组中;
- 语法:
数组1.concat(参数1,参数2,..)
- 参数可以是一个数组,也可以是一个数值;
- 特点
- (1)不会更改现有数组,产生一个新的数组;
- (2)此为深拷贝1层;
- 举例说明
-
let arr1=[1,2] let arr2=[3,4] let arr3=[5,6] //用于连接两个数组 console.log(arr1.concat(arr2)) // [1,2,3,4] //用用连接多个数组 console.log(arr1.concat(arr2,arr3)); // [1, 2, 3, 4, 5, 6] //用以连接两个数组加一个值; console.log(arr1.concat(1,arr2)) // [1, 2, 1, 3, 4]
-
[2]使用展开运算符可以将多个数组合并为1个新数组
- 作用:
将两个或多个数组中的元素添加到一个新的数组中
语法:const arr = [...arr1,...arr2]
- 特点
- (1)不会更改现有数组,产生一个新的数组;
- (2)此为深拷贝1层;
- 举例说明
-
let arr1=[1,2] let arr2=[3,4] let arr3=[5,6] //使用展开运算符连接数组 console.log([...arr1,...arr2]) // [1,2,3,4] console.log([...arr1,...arr2,...arr3]) // [1, 2, 3, 4, 5, 6]
-
[3]应用---数组降维
<script>
// 一个多维数组
let arr = [1, [2, 3], [4, [5, 1, [3]]], [4, [2, 2, [3, 4]]], [6, 7, [7]]]
// 判断数组中是否还存在数组
while (
arr.some(item => {
return Array.isArray(item)
})
) {
// 存在---因为不会改变原数组,会产生一个新的数组,所以使用原数组去接收
arr = [].concat(...arr)
// 将数组中的每个元素进行拼接(若是数具直接加入,若是数组将数组中每个元素加入)
// 第一次遍历后// [1,2,3,4,[5,1,[3]],4,[2,2,[3,4]],6,7,[7]]
}
console.log(arr)
</script>
2.将数组转化为字符串
(1)toString方法
toString()方法:数组.toString()
将数组转化为1个字符串,每个元素之间以逗号分隔;
let fruits = ['Banana', 'Orange', 'Apple', 'Mango']
console.log(fruits.toString()) //Banana,Orange,Apple,Mango
(2)join方法
join方法:数组.join('分隔符')
将数组转化为1个字符串,每个元素之间以分隔符分隔;
let fruits = [1, 2, 3, 4]
console.log(fruits.join('*')) //1*2*3*4
3.数组增删改元素方法
1.从数组尾部添加删除元素
[1]从数组尾部删除元素
语法:
数组.pop()
;一次只能删除1个元素;从数组尾部删除元素,并返回被删除的元素;
可以改变原数组;
示例:
let arr = [10,20,30,40]; let item = arr.pop(); console.log(item); // 40 console.log(arr); // [10, 20, 30]
[2]从数组尾部添加元素
1.通过数组[数组.length]=值
向数组添加元素,一次只能添加一个值;
原因:下标是从0开始编号的,数组的长度是从1开始数的,所以数组的长度与最大下标的关系是:数组的长度 = 最大下标 + 1
,也就是说数组下一个元素的下标永远是arr.length;
2.通过push方法向数组添加元素
语法:
数组.push(值1,值2,...)
向数组尾部添加元素,并返回新数组的长度
可以改变原数组;
示例:
let arr = [10,20,30,40]; let len = arr.push(50); console.log(len); // 5 console.log(arr); // [10, 20, 30, 40, 50]
2.从数组头部添加删除元素
[1]从数组头部删除元素
语法:
数组.shift()
一次只能删除一个元素从数组头部删除元素,并返回被删除的元素
可以改变原数组;
示例:
let arr = [10,20,30,40]; let item = arr.shift(); console.log(item); // 10 console.log(arr); // [20, 30, 40]
[2]从数组头部添加元素
语法:
数组.unshift(值1,值2,...)
;可以一次性添加多个元素向数组头部添加元素,并返回新数组的长度
可以改变原数组;
示例:
let arr = [10,20,30,40]; let len = arr.unshift(50); console.log(len); // 5 console.log(arr); // [50, 10, 20, 30, 40]
3.从数组中间(某个位置)添加删除元素
语法:
splice(start,num,值1,值2,...)
从数组的 start(
下标
)开始位置删除 num个元素,并新增值1,值2,...元素返回被删除元素的数组;
可以改变原数组
示例:中间删除元素
let arr = [10,20,30,40]; let item = arr.splice(2,2); console.log(item); // [30, 40] console.log(arr); // [10, 20]
示例:中间删除并添加元素
let arr = [10,20,30,40]; let item = arr.splice(2,1,'a','b','c'); console.log(item); // [30] console.log(arr); // [10, 20, "a", "b", "c", 40]
示例:中间插入元素
let arr = [10,20,30,40]; let item = arr.splice(2,0,'a','b','c'); console.log(item); // [] console.log(arr); // [10, 20, "a", "b", "c", 30, 40]
👉 如果将一个新数组,通过push、unshift添加到数组中时,会把添加的新数组整体看成一个元素,进行添加。
示例:
let arr = [10,20,30];
arr.push(['a','b','c']);
console.log(arr); // [10,20,30,['a','b','c']]
案例
案例1:去除数组中的0
需求:
将数组arr = [10,9,0,32,15,0,8]中的0移除后,形成一个新的数组。
实现:
<script> let arr = [10, 9, 0, 32, 15, 0, 8] let newArr = [] for (let i = 0; i < arr.length; i++) { if (arr[i] != 0) { newArr.push(arr[i]) } } console.log(newArr); </script>
<script> let arr = [10, 9, 0, 32, 15, 0, 8] for (let i = 0; i < arr.length; i++) { if (arr[i] === 0) { arr.splice(i, 1) } } console.log(arr) </script>
<script> let arr = [10, 9, 0, 32, 15, 0, 8] arr=arr.filter(item=>{ return item!=0 }) console.log(arr); </script>
4.从数组中切割某个片段形成一个新的数组
1.使用slice切割
语法:数组.slice(n1,n2)
;
若是没有参数,返回一个与原数组相同的数组(深拷贝1层);
有一个参数n1:若是只有1个参数则从下标n1切割至末尾;
若有两个参数n1,n2:会从下标n1
开始切割值下标n2
(不包含n2
);
不会改变原数组
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
var citrus = fruits.slice(1, 3)
console.log(citrus) //['Orange','Lemon']
console.log(fruits) //['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
2.使用splice进行切割
我们直到splice是用来删除数组的元素的,返回值是被删除的数组元素的数组,会改变原数组;
var fruits = ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
var citrus = fruits.splice(1, 2)
console.log(citrus) //['Orange', 'Lemon']
console.log(fruits) //['Banana', 'Apple', 'Mango']
3.总结
若是想获取数组中的一组数组组成一个新数组,可以使用slice方法和splice方法;
-
slice不会改变源数组;
-
splice会改变源数组;
5.对数组进行反序排列
数组.reverse
会改变原数组,不会产生新数组(返回值也是改变后的数组)
注:转置的是一维数组
let arr = [10, 9, 0, 32, 15, 0, 8]
arr.reverse()
console.log(arr) //[8,0,15,32,0,9,10]
注意点(错误案例·)---矩阵转置
<script>
let res = true
// 数组转置---转置的是一维数组,返回值为转置后的数组;注:会改变原数组
// eg:想进行3X3的矩阵转置,并与原数组进行比较(看矩阵是否对称)
// 错误点:使用原数组数据进行转置,虽然得到的新数组为转置之后的数组,但是原数组页改变了
let n1 = '110'
let n2 = '000'
let n3 = '011'
let arr = [n1.split(''), n2.split(''), n3.split('')]
let newArr = [arr[0].reverse(), arr[1].reverse(), aee[2].reverse()]
// a[0].reverse()---得到的是[0,1,1],但是于此同时a[0]也变了(改变原数组)
console.log(arr, newArr)
// 011 000 110 011 000 110
</script>
6.查找数组中是否有某个元素
1.返回值为下标
1.语法:数组.indexOf(元素)
若是数组中存在则返回下标,若是数组中不存在则返回-1
语法:数组.findIndex(item=>{return boolean}) 若是数组中存在此元素返回下标,不存在则返回-1
语法:数组.includes(item=>{return boolean} 若是数组中存在此元素返回true,不存在则返回false
2.注意:数组中的比较是===
3.使用:数组去重
<script>
let arr = [null, null, undefined, 21, 34, undefined, 45, 65, 'aaa', 45]
let newArr=[];
for(let i = 0;i < arr.length;i++) {
if(newArr.indexOf(arr[i])===-1){
// 目前新数组中并没有这个元素,添加
newArr.push(arr[i])
}
}
console.log(newArr)
</script>
2.返回值为boolean值
1.语法:数组.includes(指定元素,[指定元素])
2.返回值若是存在则返回true,否则返回false
7.数组排序
语法:数组.sort(function(v1,v2){return v1-v2})
注:会改变原数组,返回值是已经改变的数组;
总结:
可以改变原数组的方法
- 数组内置的增删元素的方法
- pop
- push
- splice
- shift
- unshift
- 转置数组方法
-
reverse
-
sort
-
5.数组解构赋值
6.数组去重
[1]使用set进行数组去重
[2]遍历去重
- 1.语法
- 数组.includes 用于检查数组中有没有此元素 若是有返回true,没有返回false;
- 数组.findIndex 用于检查数组中有没有此元素,若是有,返回下标,没有返回-1;
- 数组.indexOf()用于检查数组中有没有此元素,若是有,返回下标,没有返回-1;
- 2.代码
-
<script> let arr = [null, null, undefined, 21, 34, undefined, 45, 65, 'aaa', 45] let arr1 = [] for (let i = 0; i < arr.length; i++) { if (arr1.indexOf(arr[i]) == -1) { arr1.push(arr[i]) } } let arr2 = [] for (let i = 0; i < arr.length; i++) { if (!arr2.includes(arr[i])) { arr2.push(arr[i]) } } console.log(arr1, arr2) </script>
-
[3]为Array构造函数添加一个数组去重的方法
Array.prototype.quchong = function () {
// 数组调用这个方法,函数的tihs指向数组
return [...new Set(this)]
}
console.log(arr.quchong());
[4]数组对象去重
通过map进行数组对象去重->本篇->应用->数组对象去重
7.应用
[1]如何判断数据是否为数组
若是想看详情请看->数据类型检测
(1)方法
-
isArray(推荐使用)
-
const str = 'hello word' const arr = ['h','e','l','l','o'] const obj = { h:1, e:2, l:3 } console.log('res', Array.isArray(str), Array.isArray(arr), Array.isArray(obj)) // res false true false
-
-
Object.prototype.toString.call(value)
-
const str = 'hello word' const arr = ['h','e','l','l','o'] const obj = { h:1, e:2, l:3 } const res1 = Object.prototype.toString.call(str) // [object String] const res2 = Object.prototype.toString.call(arr) // [object Array] const res3 = Object.prototype.toString.call(obj) // [object Object]
-
(2)为什么不使用typeof检查
因为typeof检查结果具有不准确性,在检查array的结果为object
const arr = ['h','e','l','l','o']
console.log('res', typeof arr) // res object
[2]数组降维
(1)方法1
-
使用join/toString方法将数组转化为字符串(在转化为字符串的过程中会将多维数组中的元素拼接为1个字符串),再转化为数组;
-
let arr = [1,[2,3],[4,[5,[6,null,undefined,'aaa',{111:111},function(){}]]],8,9,[10]] console.log(arr.join(',').split(',')) // ['1', '2', '3', '4', '5', '6', '', '', 'aaa', '[object Object]', 'function () {}', '8', '9', '10'] console.log(arr.toString().split(','))// ['1', '2', '3', '4', '5', '6', '', '', 'aaa', '[object Object]', 'function () {}', '8', '9', '10']
-
优点
-
简单
-
-
缺点
-
元素不能正常显示;
-
数据类型全部变为字符串
-
null、undefined、object数据更是不能正确显示;
-
-
仅适用于元素为字符串、数字(类型统一)的数组;
-
(2)方法2
-
使用数组拼接的形式进行转化(递归)
-
let arr = [1,[2,3],[4,[5,[6,null,undefined,'aaa']]],8,9,[10]] while(arr.some(item=>Array.isArray(item))){ arr = [].concat(...arr) } console.log('arr', arr) // [1, 2, 3, 4, 5, 6, null, undefined, 'aaa', 8, 9, 10]
-
优点
-
数据没有变化,全部可以正常显示;
-
-
缺点
-
与方法1相比较为复杂;
-
(3)方法3
-
方法3是递归遍历,用于数组对象中的数据降维->数组扁平化处理
[3]数组排序
(1)使用sort进行数组排序;
[4]找出数组中的最大值
(1)方法1
-
Math存在一个Max方法,用于找出数据中的最大值;
-
语法
-
Math.max(value1,value2,...)
-
注:若是value中存在isNaN检测为非数字的数据--返回值将为NaN!
-
const arr1 = [1,4,5,7,9,5,1,9,3,6] const arr2 = [1,4,5,7,9,5,1,9,3,6,"11"] const arr3 = [1,4,5,7,9,5,1,9,3,6,,"11"] const arr4 = [1,4,5,7,9,5,1,9,3,6, null] const arr5 = [1,4,5,7,9,5,1,9,3,6, [12]] const arr6 = [1,4,5,7,9,5,1,9,3,6, [12,13]] console.log('res', Math.max(...arr1) , Math.max(...arr2), Math.max(...arr3), Math.max(...arr4), Math.max(...arr5), Math.max(...arr6) )// 9,11,NaN,9,12,NaN
-
-
-
实现
-
const arr = [1,4,5,7,9,5,1,9,3,6,'11',,[12],[13,14],null] const max = Math.max(...arr.filter(item => !isNaN(item))) console.log(max) // 12
-
(2)方法2
-
循环遍历寻找最大值
-
const arr = [1,4,5,7,9,5,1,9,3,6,'11',,[12],[13,14],null] let newArr = arr.filter(item => !isNaN(item)) let max = -Infinity for(const item of newArr){ if(+item > max){ max = +item } } console.log('item', max) //12
(3)方法3
-
数组排序后取第一个元素
[5]找到数组中的出现次数最多的元素和出现次数
const arr = [1,4,5,7,9,5,1,9,3,6,5,'11',,[12],[13,14],null]
let newArr = arr.filter(item => !isNaN(item))
const obj = {}
for(const item of newArr){
obj[+item] = obj[+item] ? ++obj[+item] : 1
}
const valueArr = Object.values(obj)
let value1
const value2 = Math.max(...valueArr)
for(const key in obj){
console.log('key', obj[key])
if(obj[key] == value2){
value1 = key
}
}
console.log('出现做多的是'+value1,'次数为'+value2) // 出现做多的是5 次数为3
[6]将两个有序数组合并成一个有序数组
<script>
// 不使用数组的方法-按照顺序合并
let arr1 = [1, 2, 3, 4, 5, 6, 7]
let arr2 = [4, 5, 7, 8, 9, 10]
let len = arr1.length + arr2.length
let arr = []
let i = 0
let j = 0
while (arr.length < len) {
if (i == arr1.length) {
for (let k = j; k < arr2.length; k++) {
arr.push(arr2[k])
}
} else if (j == arr2.length) {
for (let k = i; k < arr1.length; k++) {
arr.push(arr1[k])
}
} else {
if (arr1[i] > arr2[j]) {
arr.push(arr2[j])
j++
} else {
arr.push(arr1[i])
i++
}
}
}
console.log(arr)
// 使用数组的方法-先合并再排序
let newArr = [...arr1, ...arr2]
newArr.sort(function (v1, v2) {
return v1 - v2
})
console.log(newArr)
</script>
[7]在前端做分页
const index = (page -1) * size
const tableData = arr.slice(index, index+size)
-
page:当前页;
-
size:每页数量;
-
arr:返回的总数量
[8]不借助第三个变量交换两个变量的值
可以借助数组解构赋值来进行变量值的交换;
-
let a = 111 let b = 222 // Cannot create property 'undefined' on number '222' [a,b] = [b,a] console.log(a,b)
-
-
上述代码在运行过程中发现报错了;
-
原因是在写代码的过程中没有加“;”,而222与后面代码相关联·
-
let b = 222[a,b] = [b,a]
-
认为是对象获取属性值的写法;而不是代码
-
-
-
let a = 111 let b = 222; [a,b] = [b,a] // [a,b]中的[]告诉浏览器引擎右面是个数组,取数组的第一个元素赋值给a,第二个元素赋值给b console.log(a,b)
-
上述代码运行就没有问题了;
-
4.数组加引号变为字符串后,转化为数组
[1]在之前们想要将数组变化为字符串都是通过JOSN数据进行转化
- 通过JSON.stringify(数组/对象)将数组、对象转化为JSON格式的数据
- 通过JSON.parse(数组/对象)将数组、对象还原;
[2]但是若是我们拿到一个字符串为’[1,2,3]‘,通过JSON并不能将其还原,需要通过eval方法将其还原
[2.1]举例说明
// 在数据库中直接按照字符串存储的taglist
taglist=eval(taglist)
// 此时的taglist便是数组了