五、js数组
js的数组和典型数组的区别
典型数组
- 元素数据类型相同
- 连续的内存存储
- 通过数字下标获取元素
js数组
- 元素数据类型可不同
- 随机的内存存储
- 通过字符串下标获取,在使用数字下标获取时,会自动将数字转化成字符串然后再获取元素
js数组的操作
创建
直接创建的三种方式
let arr = [1,2,3] // [1,2,3]
let arr = new Array(1,2,3) // [1,2,3]
let arr = new Array(3) // // [ <3 empty items> ]
将字符串转化成数组
let arr = '1,2,3'.split(',') // ['1','2','3']
let arr = '123'.split('') // ['1','2','3']
Array.from('123') // ['1','2','3']
伪数组
定义:没有数组共用属性的数组就是伪数组
从图中可以看出,伪数组的原型链中没有数组Array的原型,所以,使用不了数组的方法
合并数组
concat() 不会改原数组
截取数组
1.slice() 不会改原数组
2.slice可以用来复制数组,对于一维数组目前我只能理解成可以深拷贝,而对于多维数组,暂且理解成第一层深拷贝,更深层则是浅拷贝(其实js只提供浅拷贝)
增加元素
push() 在尾部追加元素,返回新长度,改变原数组
let arr = [1, 2, 3];
console.log(arr.push("push")); // 4
console.log(arr); // [ 1, 2, 3, 'push' ]
unshift() 在头部插入元素,返回新长度,改变原数组
let arr = [1, 2, 3];
console.log(arr.unshift("unshift")); // 4
console.log(arr); // [ 'unshift', 1, 2, 3 ]
splice() 在中间添加元素,改变原数组
let arr = [1, 2, 3];
console.log(arr.splice(1, 0, "splice")); // []
console.log(arr); // [ 1, 'splice', 2, 3 ]
删除元素
delete
let arr = [1, 2, 3];
delete arr[0];
console.log(arr); // [ <1 empty item>, 2, 3 ] //稀疏数组
console.log(arr.length); // 3 数组的长度没变
修改length 不要随便修改length
let arr = [1, 2, 3];
arr.length = 2
console.log(arr) // [ 1, 2 ]
shift() 删除头部的元素 改变原数组
let arr = [1, 2, 3];
console.log(arr.shift()) // 1 返回被删元素
console.log(arr) // [ 2, 3 ]
pop() 删除尾部的元素 改变原数组
let arr = [1, 2, 3];
console.log(arr.pop()); // 3 返回被删元素
console.log(arr); // [ 1, 2 ]
splice() 删除中间的元素 改变原数组
let arr = [1, 2, 3];
console.log(arr.splice(1,1)); // 从索引1开始,删除一个元素 返回一个数组[ 2 ]
console.log(arr); // [ 1, 3 ]
修改元素
reverse() 反转顺序 修改原数组
let arr = [1, 2, 3];
console.log(arr.reverse()); // [ 3, 2, 1 ]
sort() 自定义顺序 修改原数组
let arr = [100, 2, 3, 999];
arr.sort((a, b) => a - b);
console.log(arr) // [ 2, 3, 100, 999 ]
查找元素
查找所有属性名
Object.keys()
let arr = [1, 2, 3, 4, 5];
arr["xxx"] = "abc";
console.log(Object.keys(arr)); // [ '0', '1', '2', '3', '4', 'xxx' ]
in
let arr = [1, 2, 3, 4, 5];
for(let key in arr){
console.log(`${key}:${arr[key]}`)
}
// 0:1
// 1:2
// 2:3
// 3:4
// 4:5
// xxx:abc
查看数字(字符串)属性名和值
for循环
let arr = [1, 2, 3, 4, 5];
arr['xxx'] = 'abc' //for循环不遍历'xxx'
arr[10] = 10
for(let i=0;i<arr.length;i++){
console.log(`${i}:${arr[i]}`)
}
// 0:1
// 1:2
// 2:3
// 3:4
// 4:5
// 5:undefined
// 6:undefined
// 7:undefined
// 8:undefined
// 9:undefined
// 10:10
forEach()
let arr = [1, 2, 3, 4, 5];
arr['xxx'] = 'abc'
arr[10] = 10
arr.forEach((item,index)=>{
console.log(`${index}:${item}`)
})
// 0:1
// 1:2
// 2:3
// 3:4
// 4:5
// 10:10
数组的高级方法
map() 映射
let arr = [1, 2, 3];
console.log(arr.map((item) => item * 2)); // [ 2, 4, 6 ]
console.log(arr); // [ 1, 2, 3 ]
filter() 过滤
let arr = [1, 2, 3];
console.log(arr.filter((item) => item % 2 === 0)); // [ 2 ]
console.log(arr); // [ 1, 2, 3 ]
reduce() 迭代
let arr = [1, 2, 3];
console.log(arr.reduce((sum, item) => sum + item, 0)); // 6
console.log(arr); // [ 1, 2, 3 ]
一道面试题
[
{ '名称': ' 动物', id: 1, parent: null },
{ '名称': '狗', id: 2, parent: 1 },
{ '名称': '猫', id: 3, parent: 1 }
]
转化为
{
children: [
{ '名称': '狗', id: 2, children: null },
{ '名称': '猫', id: 3, children: null }
],
id: 1,
'名称': ' 动物'
}
arr.reduce(
function (obj, item) {
if (item.parent === null) {
obj.id = item.id;
obj['名称'] = item['名称']
}else{
obj.children.push(item)
delete item.parent
item.children =null
}
return obj
},
{ children: [] }
)