JS数组
JS中其实没有真正的数组,只不过是用对象模拟的数组
1.初识JS数组
典型的数组
- 元素的数据类型相同
- 使用连续的内存存储
- 通过数字下标获取元素
JS的数组
元素的数据类型可以不同
内存不一定是连续的((对象是随机存储的)
不能通过数字下标,而是通过字符串下标
这意味着数组可以有任何key(下标)
-
比如
let a = [1,2,3]; a['你好'] = 1; console.log(a['你好']); // 1
- 实际上JS的数组是对象,只不过key值是字符串的数字,自带length属性
创建数组
新建
- let arr= [1,2,3]
- let arr = new Array(1,2,3)
- let arr= new Array(3)
转化
- let arr = '1,2,3'.split(',')
- let arr = '123'.split('')
- Array.from('123')
伪数组
- let divList = document.querySelectorAll('div')
- 伪数组的原型链中并没有数组的原型
合并两个数组,得到新的数组,不会改变原来的数组
- arr1.concat(arr2)
截取一个数组的一部分
- arr1.slice(1) //从第二个元素开始
- arr1.slice(0) // 全部截取 相当于拷贝复制
- 注意,JS只提供浅拷贝
2.数组元素的增删改查
删除元素
使用删除对象的方式
let arr = [a,b,c];
delete arr[0]; // 使用删除对象的方式
console.log(arr); // [empty,'b','c'] 长度不变 这样的数组叫稀疏数组
直接通过改变length删除
let arr = [1,2,3,4,5];
arr.length = 1;
console.log(arr); // Array(1)0: 1length: 1__proto__: Array(0) 长度变为1了
删除头部元素
arr.shift(l); // arr被修改,并返回被删元素
删除尾部的元素
arr.pop(); // arr被修改,并返回被删元素
删除中间的元素
arr.splice(index,1); //删除index的一个元素 arr.splice(index,1,'x'); //删除并在删除位置添加'x' arr.splice(index,1, 'x', 'y'); //删除并在删除位置添加'x', 'y'
查看所有元素
查看所有属性名
let arr = [1,2,3,4,5];
arr.x = 'xxx';
Object.keys(arr); // 或者下面for循环遍历
for(let key in arr){
console.log(`${key}:${arr[key]}`)
} // 0:1 1:2 2:3 3:4 4:5 x:xxx
只查看以数字(其实是字符串类型)为属性名的属性和值
let arr = [1,2,3,4,5,x];
for(let i = 0; i < arr.length; i++){
console.log(`${i}:${arr[i]}`)
} // 0:1 1:2 2:3 3:4 4:5
或者可以用forEach / map等原型上的函数
arr.forEach(function(item,index){
console.log(`${index}:${item}`);
}) // 0:1 1:2 2:3 3:4 4:5
// forEach原理
function forEach(array,fn){
for( let i=e; i<array .length; i++){
fn( array[i],i,array)
}
}
forEach([ 'a ' , 'b' , 'c '], function(item,index,array){
console.log(item,index,array);
})
// a 0 ['a ' , 'b' , 'c ']
// b 1 ['a ' , 'b' , 'c ']
// c 2 ['a ' , 'b' , 'c ']
查看单个属性
用对象的方式
let arr = [111,222,333];
arr[0]; // 111
索引越界问题
let arr = [111,222,333];
arr[arr.length] === undefined;
arr[-1] === undefined;
查找某个元素是否在数组里
arr.indexOf(item); // 存在返回索引,否则返回 -1
使用条件查找元素
arr.find(item => item % 2 === 0); //找第一个偶数
使用条件查找元素的索引
arr.findIndex(item => item % 2 === O); // 找到第一个偶数的索引
增加数组元素
直接使用加下标的方式增加(不推荐)
let arr = [1,2,3];
arr[3] = 4;
console.log(arr); // [1,2,3,4] length:4
// 但是如果跨下标赋值,将会变成有empty的稀疏数组
arr[99] = 99;
console.log(arr); // [1, 2, 3, 4, empty × 95, 99]
在尾部加元素
arr.push(newltem);// 修改arr,返回新长度
arr.push(item1, item2);// 修改arr,返回新长度
在头部加元素
arr.unshift(newltem);// 修改arr,返回新长度
arr.unshift(item1, item2);// 修改arr,返回新长度
在中间添加元素
arr.splice(index, 0, 'x');// 在index处插入'x'
arr.splice(index, 0, 'x', 'y');
修改数组元素
直接通过下标
arr[5] = 9;
使用splice方法
arr.splice(5, 1, 'x');// 把第五个元素删除,改为x
反转顺序
arr.reverse(); //修改原数组
自定义顺序,数组的重排序
arr.sort(); // 该方法会按照字符串或者是数组的先后顺序对数组的每一个项的字符顺序来进行排序的,如果某个项目不是字符串会先转变成字符串来进行排序,该方法会改变原始的数组,默认排序从小到大
arr.sort(function(value1,value2){ //这两个参数表示数组里面的两个项
if(value1>value2)
return -1; // 返回 -1 表示按照这个参数顺序排序从大到小排列
else if(value1<value2)
return 1; // 返回 1 表示按照这个顺序排序反过来
})
// 看一个数组对象的例子
let arr = [{name:'小明',score:99},{name:'小红',score:100},{name:'小军',score:96}];
arr.sort(function(preview,next){
if(preview.name > next.name){
return -1;
}else if(preview.name < next.name){
return 1;
}
})
console.log(arr);
// 0: {name: "小红", score: 100}
// 1: {name: "小明", score: 99}
// 2: {name: "小军", score: 96}
// 重排序的简写
let arr = [{name:'小明',score:100},{name:'小红',score:99},{name:'小军',score:96}];
arr.sort(function(preview,next){
return next.score - preview.score; // 后一个减去前一个为从大到小排列,反之则反过来
})
3.数组的变换
map方法
// map()返回一个新的数组,这个新数组的每一项都是在原始数组中的对应的数组项传入函数经过一系列处理的结果
var a = [1,2,3,4,5];
var result = a.map(function(item,index,array){
return item * 2;
});
console.log(result); //[2,4,6,8,10]
filter方法
//利用指定的return语句的条件,把所有符合条件的数组组合成一个新的数组返回
var a = [1,undefined,2,undefined,3,4,undefined,5];
var result = a.filter(function(item,index,array){
return !isNaN(item);
});
console.log(result); //[1,2,3,4,5]
reduce与reduceRight方法
// 这两个方发都会迭代数组所有的项,然后构建一个最终返回的值,其中,reduce()方法从数组的第一项开始,逐个遍历到最后,而reduceRight()则从数组的最后一项开始,向前遍历带第一项。
let a = [1,2,3,4,5];
var b = a.reduce(function(prev,cur,index,array){
return prev + cur;
},10) // 第二个参数10是可选的,作为归并的基础值
console.log(b); // 25
一道面试题
let arr = [
{名称:'动物', id: 1,parent: null},
{名称:'狗',id: 2,parent: 1},
{名称:'猫',id: 3, parent:1}
]
数组变成对象
{
id: 1,名称:'动物',children :[
{id: 2,名称:'狗',children : null},
{id: 3,名称:'猫',children : null}
]
}
答案
let newArr = arr.reduce((result, item) => {
if (item.parent === null) {
result.id = item.id
result['名称'] = item['名称'];
} else {
delete item.parent;
item.children = null;
let newObj = {};
newObj.id = item.id;
newObj.名称 = item.名称;
newObj.children = item.children;
result.children.push(newObj);
}
return result;
}, { id: null, 名称: '', children: [] }) // 创建一个新的归并的基础值