(JavaScript - 原生)数组的创建 + 数组的遍历 + es6对数组的支持 + 数组的结构化操作 + 数组的17个常用方法 + 伪数组与数组的转换 + 数组去重
还是那句话,无论是职场的老鸟还是起步的菜鸟对JavaScript中的数组肯定都是津津乐道的 ...因为它与对象是极少数可以存储多条信息并且极为常用的元素。本章节对于数组的各个方面进行详细的解说,争取真正做到深入浅出。
一、数组的创建方式
> -1).字面量式
// -1).字面量式:
let arr = [1, 2 ,3];
console.log(arr);// 打印(3) [1, 2, 3]
打印结果:↓↓↓
> -2).构造器式(new Array(Xxx))
=> 声明:
当且仅当向数组构造器仅仅传入一个数值A的话,默认是声明了一个长度为A的数组,并且数组的每一项的值用undefined来填充,而非是声明一个数组[A]。当传入的数值 >= 2个的时候,或者说传入的元素非数值就会声明[元素]这样的一个数组。
arr = null;
// -2).构造器式
arr = new Array(2);
console.log(arr, arr.length, arr[0]);// 打印 [empty × 2] 2 undefined
打印结果:↓↓↓
arr = null;
// 传入 >= 2个数值的时候
arr = new Array(2, 3);
console.log(arr);// 打印 (2) [2, 3]
arr = null;
// 传入非数值的时候
arr = new Array("好", "好", "学", "习");
console.log(arr);// 打印 (4) ["好", "好", "学", "习"]
arr = null;
arr = new Array(true,false);
console.log(arr);// 打印 (2) [true, false]
打印结果:↓↓↓
> -3).Array.of(为了解决数组构造器传入一个数值时候只是声明一个长度为n的数组而非声明一个[n]数组的问题(弥补new Array(Xxx)的不足))
arr = null;
console.log(Array.of(1));// 打印 [1]
console.log(Array.of(1, 2, 3));// 打印 (3) [1, 2, 3]
打印结果:↓↓↓
## 与上面的new Array(1)不同的是,new Array(1)是创建一个长度为1的数组,第一项值为undefined。Array.of(1)则是创建一个长度为1第一项值为1的数组,所以说就在这点上Array.of弥补了new Array的不足。
二、数组的遍历方式
arr = [1, 2, 3];
arr.fruit = "apple";
> -1).for ...
// -1).for ...
for(let i = 0;i < arr.length;i++) {
console.log(`索引:${i},值:${arr[i]}`);
}// 打印如下↓↓↓
/**
* 索引:0,值:1
* 索引:1,值:2
* 索引:2,值:3
*/
打印结果:↓↓↓
> -2).forEach() ...
// -2).forEach ...
arr.forEach((item, index) => {
console.log(`索引:${index},值:${item}`);
});// 打印如下↓↓↓
/**
* 索引:0,值:1
* 索引:1,值:2
* 索引:2,值:3
*/
打印结果:↓↓↓
> -3).for ... in ...
for(let key in arr) {
console.log(`索引:${key},值:${arr[key]}`);
}// 打印如下↓↓↓
/**
* 索引:0,值:1
* 索引:1,值:2
* 索引:2,值:3
* 索引:fruit,值:apple
*/
打印结果:↓↓↓
## 诚如大家所见(for ... in ...)遍历数组时的缺点就是会将数组的隐藏属性遍历出来,这一点不是咱们想看到的,所以使用for ... in ... 来遍历数组不是一个很好的选择
> -4).for ... of ...
// -4).for ... of ...
let num = 0;
for(let item of arr) {
console.log(`索引:${num},值:${item}`);
num++;
}// 打印如下↓↓↓
/**
* 索引:0,值:1
* 索引:1,值:2
* 索引:2,值:3
*/
打印结果:↓↓↓
三、ES6对数组的支持
> -1).扩展运算符(...)
// ... 扩展运算符 => 将数组拆分
console.log(...arr);// 打印 1 2 3
打印结果:↓↓↓
四、数组的结构化操作
> -1).filter(过滤的意思 -> 删除)
// filter过滤的意思 -> 删除
console.log(arr.filter((item, index) => item > 2));// 打印 [3]
打印结果:↓↓↓
## 将arr数组中的所有 >2 的元素过滤出来
> -2).map(映射的意思 -> 将原有的数组中的数据映射成另一种形式)
// map映射的意思 -> 将原有的数组中的数据映射成另一种形式
document.body.innerHTML = arr.map((item, index) => `<li>${item}</li>`).join("");
结果:↓↓↓
## 将arr数组映射成3个带有数组值的<li>number</li>的标签
> -3).reduce -> 归并
## 核心思想就是,此次回调函数的结果就是prev的值,next的值是下一次运算的结果
## 常用的场景:
A.数组求和
console.log(arr.reduce((prev, next) => prev + next));// 打印 6
打印结果:↓↓↓
B.解析完的json数据求和
## 如果这样写:
let data = [{
num: 1,
price: 100
},{
num: 2,
price: 100
},{
num: 3,
price: 100
}];
console.log(data.reduce((prev, next) => (prev.num * prev.price) + (next.num * next.price)));// 抛出异常
第一次回调函数完成之后将计算出来的一个Number型的数值赋值给prev,第二轮计算的时候(prev此时已经是个数值了)数值.num、数值.price可能吗(基本数据类型定义属性是无意义的)??所以还会抛出异常。
所以我们如下写:后面的第二参数0就是默认加在数组中的第一项,并且不再需要prev调用属性去计算了,这样一来就变成了数与数之间的运算。
prev:0 next:1 * 100 => prev: 0 + 1 * 100
prev:100 next:2 * 100 => prev:100 + 2 * 100
prev:300 ...
// 对于解析好的json数据,对其进行归并操作
let data = [{
num: 1,
price: 100
},{
num: 2,
price: 100
},{
num: 3,
price: 100
}];
console.log(data.reduce((prev, next) => prev + (next.num * next.price), 0));// 打印 600
打印结果:↓↓↓
五、数组的17个常用方法
> -1).数组的CUD(增删改)
①.增:
⑴.下标法
// A.下标法:
arr[arr.length] = 4;
console.log(arr);// 打印 (4) [1, 2, 3, 4]
打印结果:↓↓↓
⑵.push法
/**
* -1).用途:在数组末尾添加一个元素
* -2).用法:arr.push(num);
* -3).是否改变原数组:是
* -4).返回值:返回当前添加完元素的数组的长度
*/
// B.push(Xxx);
console.log(arr.push(5));// 打印 5
console.log(arr);// 打印 (5) [1, 2, 3, 4, 5]
打印结果:↓↓↓
⑶.unshift法
/**
* -1).用途:在数组前方添加一个元素
* -2).用法:arr.unshift(num);
* -3).是否改变原数组:是
* -4).返回值:返回当前添加完元素的数组的长度
*/
// C.unshift(Xxx);
console.log(arr.unshift(0));// 打印 6
console.log(arr);// 打印 (6) [0, 1, 2, 3, 4, 5]
打印结果:↓↓↓
⑷.splice(目标索引始, 删除元素个数, 替换元素)
/**
* -1).用途:在数组任意地方添加一个元素
* -2).用法:arr.splice(startIndex, removeNum, replaceEle);
* -3).是否改变原数组:是
* -4).返回值:返回删除的元素组成的新数组
*/
console.log(arr.splice(arr.length, 0, 7));// 打印 []
console.log(arr);// 打印 (7) [0, 1, 2, 3, 4, 5, 7]
打印结果:↓↓↓
②.删:
⑴.下标法
let arr_copy = [1, 2];
arr_copy.length -= 1;
console.log(arr_copy);//打印 [1]
打印结果:↓↓↓
⑵.pop法
/**
* -1).用途:在数组末尾删除一个元素
* -2).用法:arr.pop();
* -3).是否改变原数组:是
* -4).返回值:返回删除的元素
*/
// A.pop();
console.log(arr.pop());// 打印 7
console.log(arr);// 打印 (6) [0, 1, 2, 3, 4, 5]
打印结果:↓↓↓
⑶.shift法
/**
* -1).用途:在数组前方删除一个元素
* -2).用法:arr.shift();
* -3).是否改变原数组:是
* -4).返回值:返回删除的元素
*/
console.log(arr.shift());// 打印0
console.log(arr);// 打印 (5) [1, 2, 3, 4, 5]
打印结果:↓↓↓
⑷.splice(目标索引始, 删除元素个数)
/**
* -1).用途:在数组中任意地方删除一个元素
* -2).用法:arr.splice(目标索引始, 删除元素个数);
* -3).是否改变原数组:是
* -4).返回值:返回删除的元素组成新数组
*/
console.log(arr.splice(arr.length - 1, 1));// 打印 [5]
console.log(arr);// 打印 (4) [1, 2, 3, 4]
打印结果:↓↓↓
③.改:
⑴.下标法
// 下标方法:
arr_copy[0] = 101;
console.log(arr_copy);// 打印 [101]
打印结果:↓↓↓
⑵.splice(目标索引始, 删除元素个数, 替换元素)
/**
* -1).用途:在数组中任意地方替换一个/多个元素
* -2).用法:arr.splice(目标索引始, 删除元素个数, 替换元素);
* -3).是否改变原数组:是
* -4).返回值:返回删除的元素组成新数组
*/
// A.splice(目标索引始, 删除元素个数, 替换元素)
console.log(arr.splice(arr.length - 1, 1, 5));// 打印 [4]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
> -2).数组的截取与拼接
①.截取
⑴.slice法
/**
* -1).用途:在数组中截取一段数值
* -2).用法:arr.slice(起始索引, 目标索引);
* -3).是否改变原数组:否
* -4).返回值:返回截取的元素组成新数组
*/
console.log(arr.slice(0, 2));// 打印 (2) [1, 2]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
##延伸 ...数组的克隆
// 所以可以实现数组的克隆
console.log(arr.slice(0, arr.length));// 打印 (4) [1, 2, 3, 5]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
②.拼接
⑴.concat法
/**
* -1).用途:将一个数组与另一个数组进行拼接
* -2).用法:arr.concat(arr_1);
* -3).是否改变原数组:否
* -4).返回值:返回拼接后新数组
*/
// A.concat(Xxx);
let arr_1 = [7, 8, 9];
console.log(arr.concat(arr_1));// 打印 (7) [1, 2, 3, 5, 7, 8, 9]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
⑵.通过ES6数组的扩展运算符进行拼接
// B. ... ES6数组的扩展运算符呀
console.log([...arr,...arr_1]);// 打印 (7) [1, 2, 3, 5, 7, 8, 9]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
> -3).数组的序列化
①.toString法
/**
* -1).用途:将一个数组序列化为用逗号分隔的字符串
* -2).用法:arr.toString();
* -3).是否改变原数组:否
* -4).返回值:返回用逗号分隔的字符串
*/
// -1).toString();
console.log(arr.toString());// 打印 1,2,3,5
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
②.join法
/**
* -1).用途:将一个数组序列化为用指定符号分隔的字符串
* -2).用法:arr.join("分隔符");
* -3).是否改变原数组:否
* -4).返回值:返回用指定符号分隔的字符串
*/
// -2).join("分隔符");
console.log(arr.join("^"));// 打印 1^2^3^5
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
> -4).数组的排序
①.reverse法
/**
* -1).用途:将一个数组倒序
* -2).用法:arr.reverse();
* -3).是否改变原数组:是
* -4).返回值:返回倒序后的新字符串
*/
// -1).reverse();倒序
console.log(arr.reverse());// 打印 (4) [5, 3, 2, 1]
console.log(arr);// 打印 (4) [5, 3, 2, 1]
打印结果:↓↓↓
②.sort法
/**
* -1).用途:将一个数组排序
* -2).用法:arr.sort((a, b) => a - b(从小到大)/b-a(从大到小));
* -3).是否改变原数组:是
* -4).返回值:返回排序后的新字符串
*/
// -2).sort();排序
console.log(arr.sort((a, b) => a - b));// 打印 (4) [1, 2, 3, 5]
console.log(arr);// 打印 (4) [1, 2, 3, 5]
打印结果:↓↓↓
> -5).数组的查找元素的方法
①.indexOf(元素);在指定数组中查找指定元素所在的位置(从头向后找) / lastIndexOf(元素);(从后向前找)
// -1).indexOf(元素)/lastIndexOf(元素)
console.log(arr.indexOf(2));// 打印 1
打印结果:↓↓↓
②.includes(元素);在指定数组中查找指定元素,如果存在返回true,不存在返回false
// -2).includes(元素);
console.log(arr.includes(3));// 打印 true
打印结果:↓↓↓
③.find(回调函数);通过设置会回调函数规则,返回符合规则的数值
// -3).find()
console.log(arr.find((n) => n < 2));// 打印 1
打印结果:↓↓↓
④.findIndex(回调函数);通过设置会回调函数规则,返回符合规则的数值所在的位置
// -4).findIndex();
console.log(arr.findIndex((n) => n < 2));// 打印 0
打印结果:↓↓↓
⑤.fill(替换的元素, 开始的索引, 结束的索引);替换一个甚至多个元素 => 会改变原数组
// -5).fill(替换的元素, 开始的索引, 结束的索引 );
console.log(arr.fill(101, 0, 1));// 打印 (4) [101, 2, 3, 5]
console.log(arr);// 打印 (4) [101, 2, 3, 5]
打印结果:↓↓↓
六、伪数组 => 数组
先创建一个伪数组:
// 伪数组 -> 数组
let arr_fake = {
0: 100,
1: 200,
2: 300,
length: 3
};
console.log(Object.prototype.toString.call(arr_fake));// 打印 [object Object]
console.log(arr_fake);// 打印 {0: 100, 1: 200, 2: 300, length: 3}
console.log(`数组长度:${arr_fake.length},第二个元素值${arr_fake[1]}`);// 打印 数组长度:3,第二个元素值200
打印结果:↓↓↓
将伪数组转换为数组:
let arr_array = Array.from(arr_fake);
console.log(Object.prototype.toString.call(arr_array));// 打印 [object Array]
console.log(arr_array);// 打印 (3) [100, 200, 300]
打印结果:↓↓↓
七、数组去重
> -1).ES5及ES5之前的数组去重
// ES5数组去重
var arr_es5 = [1, 2, 2, 3];
var arr_es5Copy = [];
for(var i = 0;i < arr_es5.length;i++) {
if(arr_es5Copy.indexOf(arr_es5[i]) === -1) {
arr_es5Copy.push(arr_es5[i]);
}
}
console.log(arr_es5Copy);// 打印 (3) [1, 2, 3]
console.log(arr_es5);// 打印 (4) [1, 2, 2, 3]
打印结果:↓↓↓
> -2).利用对象属性的不可重复性
let ary = [1, 12, 3, 24, 1, 3, 2, 8];
let obj = {};// 定义一个空对象
// 遍历数组的每一项,将其每一项填入obj对象的属性名中去(实际上已经实现了去重)
ary.forEach((item, index) => obj[item] = undefined);
// 获取obj对象上所有的键
let arr_1 = Object.keys(obj);
// 将其String -> Number
arr_1 = arr_1.map((item, index) => Number(item));
// 打印结果
console.log(arr_1);
打印结果:↓↓↓
> -3).ES6数组去重
// ES6数组去重
let set = new Set(arr_es5);
console.log([...set]);// 打印 (3) [1, 2, 3]
打印结果:↓↓↓
总结:以上就是本次数组专题的主要内容,涵盖(数组的创建、数组的遍历、es6对数组的支持、数组的结构化操作、 数组的17个常用方法、ES5/6数组去重)方面。每个方法都有解说与案例,希望对大家和自己有所帮助。如有不正确或者建议请在下方留言,博主会在第一时间回复!!!