前言
数组是多个变量值的集合,数组是Array 对象的实例,所以可以像对象一样调用方法。(js中数组是一种特殊的对象)本文目的是为大家梳理清除所有与数组类型相关的操作和技巧
1.数组是引用类型,是地址传递
那也就说const定义的数组我们也可以对其内容进行修改
console.table() 以表格的形式展示数组
const arr =["舒淇","张嘉倪"];
console.table(arr);
arr[1] = "迪丽热巴";
console.table(arr);
2.Array.of()和 new Array()对数字的处理不同
let arr = Array.of("舒淇","唐嫣");
console.table(arr);
let arr2 = new Array("刘亦菲","马保国");
console.table(arr2);
let arr3 = Array.of(6);
console.table(arr3);//Array.of()方法会将数字当成值
let arr4 = new Array(6);//new Array()方法会将数字当成长度
console.table(arr4);//这里打印不出来是因为创建了长度为6的空数组
console.log("arr4的长度:",arr4.length);
3.Array.isArray()检测是否是数组
let arr = Array.of("舒淇","唐嫣");
console.log(Array.isArray(arr));//true
4.join数组转字符串连接符
let arr = Array.of("abc","def","jqk");
console.log(arr.join());//abc,def,jqk
console.log(arr.join("==="));//abc===def===jqk
反过来字符串转数组可以使用split
let a = "abc,def,jqk";
console.log(a.split());//['abc', 'def', 'jqk']
也可以使用Array.from()
let a = "abc,def,jqk";
console.log(Array.from(a));//['a', 'b', 'c', ',', 'd', 'e', 'f', ',', 'j', 'q', 'k']
5.数组展开语法
展开语法用来合并数组
let a = [1, 2, 3];
let b = ['a', 'b', ...a];
console.log(b); //['a', 'b', 1, 2, 3]
可以利用展开语法向函数中传递任意数量的参数
function abc(...args){
let sum=0;
for(let i=0; i<args.length; i++){
sum+=args[i];
}
return sum;
}
console.log(abc(1,2,3,4,5)); // 输出:15
可以利用展开语法将DOM节点转为数组后,可利用数组方法操作DOM
let btns = document.querySelectorAll('button');
console.log(Array.isArray(btns));//false
console.log(Array.isArray([...btns]));//true
6.解构赋值
解构赋值是一种 JavaScript 表达式,它允许我们从数组或对象中提取数据,并赋值给其他变量。这是 ECMAScript 6 引入的一种新语法,使我们能更轻松地从数组和对象中获取值。
let arr = ["John", "Smith"];
let [firstName, surname] = arr;
console.log(firstName); // 输出:John
console.log(surname); // 输出:Smith
在上述代码中,["John", "Smith"]是一个数组,[firstName, surname] = arr;是一个解构赋值的表达式。通过这个表达式,我们把数组arr的第一个元素赋值给了变量firstName,第二个元素赋值给了变量surname。
对象的解构赋值中变量的名字必须和对象的属性名相同。
let obj = {a: 1, b: 2};
let {a, b} = obj;
console.log(a); // 输出:1
console.log(b); // 输出:2
如果将 let obj = {a: 1, b: 2};换成let obj = {aa: 1, bb: 2};
a和b并不对应obj对象的任何属性(obj的属性是aa和bb),所以这个解构赋值是错误的。
结合上面的展开语法举一反三:
let [a, ...b] = ['北极鲇鱼', '上海名媛', '西安泡沫'];
console.log(b);// ['上海名媛', '西安泡沫']
在函数中也可以解构赋值:
function hd([a, b]) {
console.log(a, b);
}
hd(['周杰伦', "林俊杰"]);
7.数组首尾 操作"四金刚"
四金刚包括:push(),pop(),shift(),unshift()
push():压入元素,直接改变元数组,返回值为数组元素数量
pop():从末尾弹出元素,直接改变元数组,返回值为弹出的元素
shift():从数组前面取出一个元素
let arr = ['a','b','c'];
let value = arr.shift();
console.log(value);//a
console.table(arr);//['b','c']
unshift():从数组前面添加元素
8.使用fill 填充数组元素
let arr = ['a','b','c','d'];
arr.fill("凉皮",1,3);
console.log(arr);//['a', '凉皮', '凉皮', 'd']
可以发现fill('值',开始位,结束位)其中不包含结束位置。
9.使用 slice 方法从数组中截取部分元素组合成新数组
let arr = ['a','b','c','d'];
let arrA = arr.slice(1,3);
console.log(arr);//['a', 'b', 'c', 'd']
console.log(arrA);//['b', 'c']
原数组并没有改变,和fill一样,结束位置也是不包含在内,
如果只写开始位,不写结束位,那么相当于从开始位到数组结束
let arr = ['a','b','c','d'];
let arrA = arr.slice(1);
console.log(arr);//['a', 'b', 'c', 'd']
console.log(arrA);//['b', 'c','d']
10.使用 splice 方法可以添加、删除、替换数组中的元素,会对原数组进行改变,返回值为数组的元素。
删除:删除数组元素第一个参数为从哪开始删除,第二个参数为删除的数量。
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(1, 3)); //返回删除的元素 [1, 2, 3]
console.log(arr); //删除数据后的原数组 [0, 4, 5, 6]
替换:
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(1, 3, 'a', 'b')); //[1, 2, 3]
console.log(arr); //[0, 'a', 'b', 4, 5, 6]
向末尾添加元素:
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(arr.length, 0,'a', 'b','c'));
console.log(arr); //[0, 1, 2, 3, 4, 5, 6, 'a', 'b', 'c']
splice方法的第二个参数应该是一个数字,表示要移除的元素数量。如果你传入的是一个非数字的值(比如 'a'),JavaScript 会尝试将其转换为数字。在这种情况下,'a' 转换为数字会得到 NaN,所以 splice() 不会移除任何元素。
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(arr.length,'a', 'b','c'));
console.log(arr); //[0, 1, 2, 3, 4, 5, 6, 'b', 'c']
相同的逻辑,如果splice第一个参数是0,第二个参数也是0;那么就相当于unshift()函数
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(0,0,'a', 'b','c'));
console.log(arr); //['a', 'b', 'c', 0, 1, 2, 3, 4, 5, 6]
11.清空数组
可以利用length清空数组:
let a = [1,2,3];
a.length = 0;
console.log('打印a',a);//[]
需要强调的是:
let a = [];这种清空数组的方法,是创建一个新的空数组
先看代码,既然知道数组是地址传递那么是不是认为删除b以后a也为空?
let a = [1,2,3];
let b =a;
console.log('打印b',b);
b=[];
console.log('打印删除后b',b);
console.log('打印a',a);
看结果a并没有为空
这是因为执行 b = [] 时,实际上是创建了一个新的空数组,并将 b 的引用指向这个新数组。这并不会影响到 a,因为 a 仍然指向原来的数组。
12.与点语法功能相同的concat
就是合并数组的
let a =[1,2,3];
let b=[4,5,6];
b= b.concat(a);
console.log(b)//[4, 5, 6, 1, 2, 3]
13.copyWithin
arr.copyWithin(target, start, end)
target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
let array = [1, 2, 3, 4, 5];
array.copyWithin(0, 3);
console.log(array); // 输出:[4, 5, 3, 4, 5]
在这个例子中,我们将从索引3开始的元素(4和5)复制到从索引0开始的位置,所以结果数组变为了[4, 5, 3, 4, 5]。
需要注意的是,copyWithin()是在原数组上进行修改,不会返回一个新的数组。
14.查找元素之indexOf
使用 indexOf 从前向后查找元素出现的位置,如果找不到返回 -1。
let arr = [7, 3, 2, 8, 2, 6];
console.log(arr.indexOf(2)); // 2 从前面查找2出现的位置
indexOf 类似是严格类型约束
let arr = [7, 3, 2, '8', 2, 6];
console.log(arr.indexOf(8)); // -1
indexOf第二个参数是用于指定查找开始位置
let arr = [7, 3, 2, 8, 2, 6];
//从第二个元素开始向后查找
console.log(arr.indexOf(2, 3)); //4
lastIndexOf是从后向前查找:
let arr = [7, 3, 2, 8, 2, 6];
//从第二个元素向前查找
console.log(arr.lastIndexOf(2,2));//2
15.查找元素之includes
返回布尔类型
let arr = [1,2,3,4];
console.log(arr.includes(1)); //true
includes()方法在处理引用类型(如对象、数组)时,会比较它们的引用,而不是它们的内容。这意味着,即使两个对象具有相同的属性和值,includes()也会认为它们是不同的,因为它们在内存中的位置是不同的。
let arr = [{ name: 'Alice' }, { name: 'Bob' }];
console.log(arr.includes({ name: 'Alice' })); // 输出:false
includes实现方法:
function includes(array, item) {
for (const value of array)
if (item === value) return true;
return false;
}
console.log(includes([1, 2, 3, 4], 3)); //true
16.查找元素之find与findIndex
find() 方法需要一个测试函数作为参数,而不是一个字符串。这个测试函数会对数组中的每个元素执行,并返回第一个使得该函数返回 true 的元素。
let arr = ["abc", "def", "qwe"];
let abc = arr.find(item => item === "def");
console.log(abc);//def
find可以方便的查找引用类型:
const user = [{ name: "李四" }, { name: "张三" }, { name: "王五" }];
const find = user.find(user => (user.name = "张三"));
console.log(find);//{name: '张三'}
findIndex 与 find 的区别是返回索引值
const user = [{ name: "李四" }, { name: "张三" }, { name: "王五" }];
const find = user.findIndex(function (v) {
return v.name == '王五';
})
console.log(find);//2
17.数组排序之反转数组顺序reverse
let arr=[1,2,3,4,5,6,7,8,9,10];
console.log(arr.reverse());//[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
18.数组排序之顺序排列sort
在最简单的形式中,sort()方法会按照字符串的Unicode码点进行排序。例如:
let arr = ["Banana", "Apple", "Mango", "Orange"];
arr.sort();
console.log(arr); // 输出:["Apple", "Banana", "Mango", "Orange"]
数字排序
默认的排序方式可能不适用于数字数组,因为它会将数字转换为字符串进行比较。例如,数字100会被排在25之前,因为字符串"100"在Unicode顺序中排在"25"之前。为了正确地排序数字,你可以向sort()方法提供一个比较函数:
let arr = [40, 100, 1, 5, 25, 10];
arr.sort(function(a, b) {
return a - b;
});
console.log(arr); // 输出:[1, 5, 10, 25, 40, 100]
这个比较函数接受两个参数a和b,如果a应该排在b之前,那么比较函数应该返回一个小于0的值。如果a应该排在b之后,那么比较函数应该返回一个大于0的值。如果a和b相等,那么比较函数应该返回0。
注意事项
sort()方法会改变原始数组,而不是创建一个新的排序后的数组。
如果没有提供比较函数,所有非undefined的数组元素都会被转换为字符串,并按照UTF-16码元顺序比较字符串进行排序。
19.数组循环遍历之for循环
根据数组长度结合for 循环来遍历数组
let lessons = [
{name: '小明',age: 18},
{name: '小李',age: 17},
{name: '大明',age: 28},
];
for (let i = 0; i < lessons.length; i++) {
lessons[i] = `姓名: ${lessons[i].name} 年龄:${lessons[i].age}`;
}
console.log(lessons);//['姓名: 小明 年龄:18', '姓名: 小李 年龄:17', '姓名: 大明 年龄:28']
20.数组循环遍历之forEach循环
forEach使函数作用在每个数组元素上
let lessons = [
{name: '小明',age: 18},
{name: '小李',age: 17},
{name: '大明',age: 28},
];
lessons.forEach((item, index, array) => {
item.age = item.age-5;
});
console.log(lessons);
21.数组循环遍历之for/in循环
遍历时取键名
let people = [
{name: '小明',age: 18},
{name: '小李',age: 17},
{name: '大明',age: 28},
];
for (const key in people) {
console.log(`索引: ${key} ${people[key].name}`);
}
22.数组循环遍历之for/of 循环
与 for/in 不同的是 for/of 每次循环取键值
let people = [
{name: '小明',age: 18},
{name: '小李',age: 17},
{name: '大明',age: 28},
];
for (const key of people) {
console.log(key)
}
for (const key in people) {
console.log(key)
}
23.数组循环遍历之迭代器方法keys和values
let arr = ['abc','def'];
let keys = arr.keys();
let values = arr.values();
//通过迭代器打印key和value
console.log('键'+keys.next().value );
console.log('键'+values.next().value );
entries是返回数组所有键值对
let arr = ['abc','def'];
console.log(arr.entries().next().value)//[0, 'abc']
24.数组every和some方法
every和some都是数组的迭代方法,它们都会遍历数组并返回一个布尔值。但是,它们的工作方式和返回的结果有所不同。
every方法用于检测数组中的所有元素是否都满足指定条件。如果所有元素都满足条件,它将返回true;如果有一个元素不满足条件,它将返回false并停止检测剩余的元素。对于空数组,every方法不会进行检测,直接返回true;
let arr = [1, 2, 3, 4, 5];
let result = arr.every(item => item > 0); // 返回true,因为所有元素都大于0
console.log(result); // 输出:true
some方法用于检测数组中是否有至少一个元素满足指定条件。如果有一个元素满足条件,它将返回true并停止检测剩余的元素;如果所有元素都不满足条件,它将返回false。对于空数组,some方法不会进行检测,直接返回false。
let arr = [1, 2, 3, 4, 5];
let result = arr.some(item => item > 5); // 返回false,因为没有元素大于5
25.数组过滤元素filter
let people = [
{name: '小明',age: 18},
{name: '小李',age: 17},
{name: '大明',age: 28},
];
let arr=people.filter(function(item,index,array){
if(item.age>=18){
return true;
}
})
console.table(arr);
console.table(people);
</script>
26.Map和Array.prototype.map()
Map对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为键或值。Map对象是键值对的集合,Map中的一个键只能出现一次;它在Map的集合中是独一无二的。Map对象按键值对迭代——一个for…of循环在每次迭代后会返回一个形式为[key, value]的数组。
const contacts = new Map();
contacts.set("Jessie", { phone: "213-555-1234", address: "123 N 1st Ave" });
console.log(contacts.has("Jessie")); // true
contacts.get("Hilary"); // undefined
contacts.set("Hilary", { phone: "617-555-4321", address: "321 S 2nd St" });
contacts.get("Jessie"); // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete("Raymond"); // false
contacts.delete("Jessie"); // true
console.log(contacts.size); // 1
Array.prototype.map()方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。map()方法按照原始数组元素顺序依次处理元素。
const numbers = [1, 4, 9];
const doubles = numbers.map((num) => num * 2);
console.log(doubles); // [2, 8, 18]
console.log(numbers); // [1, 4, 9]
27.reduce
reduce是JavaScript中Array对象的一个方法,它对数组中的每个元素执行一个由你提供的reducer函数,按照数组的顺序,将其结果汇总为单个返回值。
reduce的语法如下:
array.reduce(function(返回值, 当前值, 下标, 原数组), 指定返回值);
通过代码感受一下
let arr = ['a','b','c','d','e','f'];
arr.reduce(function(pre,value,index,arr){
console.log(pre,value,index,arr);
})
可以发现如果没有填指定返回值的话,返回值第一次返回第一个元素a
let arr = ['a','b','c','d','e','f'];
arr.reduce(function(pre,value,index,arr){
console.log(pre,value,index,arr);
return 123;
})
如果函数有返回值,那么除了第一次以外,都可以看到函数的返回值123。
let arr = ['a','b','c','d','e','f'];
arr.reduce(function(pre,value,index,arr){
console.log(pre,value,index,arr);
return 123;
},456)
上面这段代码,我们设置了“指定返回值”,可以发现第一次的返回值变成了我们设置的456,其余返回值还是函数的返回值123
了解了规则之后,我们可以利用reduce来为我们进行比较和求和汇总
求和:
let arr = [1, 2, 3, 4, 5];
let sum=arr.reduce(function(pre, value,index,arr){
return pre + value
}, 0);
console.log(sum);//输出15
求最大值:
let arr = [1, 2, 3, 4, 5];
let max = arr.reduce((pre,value,index,arr) =>{
return pre > value ? pre : value;
},0);
console.log(max);
数组去重:
let arr = [1, 2, 3, 3,5,4, 5];
let newArr = arr.reduce((pre,value) => {
if(!pre.includes(value)){
return pre.concat(value);
// return [...pre,value];
}else{
return pre;
}
},[]); // 输出:[1, 2, 3, 4,5]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。