一、会改变原数组方法
1.1、splice(增删改)
splice()
方法可以删除、插入、替换数组中的元素。返回一个数组,里面包含了被删除的元素,没有则返回空数组- 语法:
/*
start: 必填,指定修改的开始位置(从0计数)
deleteCount:可选,为整数,表示要移除的数组元素的个数,从start 位置开始。
itemN:可选,可多个,表示要添加进数组的元素,从start 位置开始。
*/
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
// 描述
- start 如果超出了数组的长度,则从数组末尾开始添加内容
- start 如果为负数,意味着-n是倒数第n个元素并且等价于array.length-n);
- start 如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
- deleteCount 如果不填或者大于start 之后的元素的总数,则删除start 之后的所有元素
- deleteCount 如果是 0 或者负数,则不移除元素。
- itemN 如果不指定,则将只删除数组元素,不新增。
// 返回值
- 由被删除的元素组成的一个数组。
- 如果只删除了一个元素,则返回只包含一个元素的数组。
- 如果没有删除元素,则返回空数组。
- 示例:
// 删除元素
let colors = ['red','green','blue'];
let removed = colors.splice(0,1); // 删除一项
console.log(colors); // ['green','blue']
console.log(removed); // ['red'] 只有一个元素的数组
// 插入元素
let colors2 = ['red','green','blue'];
let removed2 = colors2.splice(1,0,'yellow','orange'); //在索引位置 1 插入两个元素
console.log(colors2); // ['red','yellow','orange','green','blue']
console.log(removed2); // [] 空数组
// 修改元素
let colors3 = ['red','green','blue'];
let removed3 = colors3.splice(1,1,'yellow','orange'); // 先删除后插入
console.log(colors3); // ['red','yellow','orange','blue']
console.log(removed3); // ['green'] 只有一个值的数组
1.2、shift(删除首项)
shift
:删除数组第一项,并返回被删除的元素。
var arr = [1,2,3]
var val = arr.shift();
console.log('被删除的元素:', val) // 1
console.log('改变后的元素:', arr) // [2, 3]
// 不能在 log 这样打印被删除的元素,不然会默认执行一次
// console.log('被删除的元素:', arr.shift())
1.3、unshift(添加首项)
unshift
:添加数组第一项,并返回新的数组长度。
var arr = [1, 2, 3]
var val = arr.unshift(0);
console.log('返回数组长度:', val) // 4
console.log('改变后的数组:', arr) // [0, 1, 2, 3]
1.4、pop(删除尾项)
pop
:删除数组最后一项,并返回被删除的项。
var arr = [1, 2, 3]
var val = arr.pop();
console.log('返回数组长度:', val) // 3
console.log('改变后的数组:', arr) // [1, 2]
1.5、push(添加尾项)
push
:添加数组最后一项,并返回新的数组长度。
var arr = [1, 2, 3]
var val = arr.push(4);
console.log('返回数组长度:', val) // 4
console.log('改变后的数组:', arr) // [1, 2, 3, 4]
1.6、sort(数组排序)
sort()
:按照UTF-16代码单元值序列升序从新排列数组元素,即最小的值在前面,最大的值在后面
var arr = [1, 3, 2, 10]
var val = arr.sort();
console.log('val =', val) // [1, 10, 2, 3]
console.log('arr =', arr) // [1, 10, 2, 3]
- 想直接使用
sort
对数字大小进行排序是不太可能的,因为它默认比较的是数组元素在unicode
编码中的位置高低 - 所以
sort
方法还可以接受一个比较函数,用返回值来判断哪个值该排在前面
compareFn(a, b) 返回值 | 排序顺序 |
---|---|
大于 0 | a 在 b 后,如 [b, a] |
小于 0 | a 在 b 前,如 [a, b] |
等于 0 | 保持 a 和 b 原来的顺序 |
//升序排序
function ascending(a, b){
if(a < b){
return -1;
}else if(a > b){
return 1;
}else{
return 0;
}
}
//降序排序
function descending(a, b){
if(a < b){
return 1;
}else if(a > b){
return -1;
}else{
return 0;
}
}
- 比较函数可以适用于大多数数据类型,可以把它当做参数传给sort()方法
let values = [1,0,5,15,10];
values.sort(ascending); // 调用升序函数 ascending()
console.log(values); // 打印数组:0,1,5,10,15
values.sort(descending); //调用降序函数 descending()
console.log(values); // 打印数组:15,10,5,1,0
- 此外,这个比较函数也可以简写为一个箭头函数
let values = [1,0,5,15,10];
values.sort((a,b) => a < b ? -1 : a > b ? 1 : 0); //调用升序函数
console.log(values); //打印数组:0,1,5,10,15
values.sort((a,b) => a < b ? 1 : a > b ? -1 : 0); //调用降序函数
console.log(values); //打印数组:15,10,5,1,0
- 如果数组的元素是
number
类型(如果不是,也先可以先转number,比如下例的时间类型),比较函数还可以这样写:
//升序排序
function ascending(a, b){
return a - b;
}
//降序排序
function descending(a, b){
return b - a; // 等价于 -(a - b);
}
// 示例:
// 数值格式
[1,0,5,15,10].sort((a,b)=> a - b); // 升序-小到大
[1,0,5,15,10].sort((a,b)=> b - a); // 降序-大到小
// 日期格式
["2023-07-26 16:11:02", "2023-05-24 17:18:55"].sort((a,b)=> new Date(a) - new Date(b)); // 升序-小到大
["2023-07-26 16:11:02", "2023-05-24 17:18:55"].sort((a,b)=> new Date(b) - new Date(a)); // 降序-大到小
1.7、reverse(反转数组)
reverse()
:只是仅仅将数组中的元素进行反向排列
var arr = [1, 3, 2]
var val = arr.reverse();
console.log('val =', val) // [2, 3, 1]
console.log('arr =', arr) // [2, 3, 1]
二、不改变原数组方法
2.1、at(索引取值)
at()
方法:接收一个整数值并返回该索引的项目,允许正数和负数。负整数从数组中的最后一个项目开始倒数。- 优势在于比
length
属性写法更简洁 - 基本用法:
// 数组及数组元素。
const colors = ['red', 'green', 'blue'];
// 使用长度属性。
console.log(colors[colors.length-1]); // 'blue'
console.log(colors[colors.length-2]); // 'green'
// 使用 at() 方法。
console.log(colors.at(0)); // 'red'
console.log(colors.at(1)); // 'green'
console.log(colors.at(-1)); // 'blue'=
2.2、join(转字符串)
join()
方法:接收一个参数,即字符串分隔符,返回包含所有项的字符串- 语法:
/*
separator:可选,指定一个字符串来分隔数组的每个元素
*/
arr.join([separator])
// 参数
- 如果 separator 不填, 数组元素用 逗号(,)分隔。
- 如果 separator 是空字符串 (""),则所有元素之间都没有任何字符。
- 如果 separator 是未定义的 (undefined),则数组元素用 逗号(,)分隔。
- 如果数据里面有元素为 undefined 或 null,它会被转换为空字符串。
// 返回值
- 一个所有数组元素连接的字符串
- 调用 join 方法可以得到与调用toSting方法相同的结果
- 如果不给join传入参数,或者传入的参数为undefined,则仍然使用‘,’号作为分隔符
let colors = ['red','greeen','blue'];
// 不传参数,默认","号分割
console.log(colors.join()); // 打印结果:red,greeen,blue
// 参数为 undefined,默认","号分割
console.log(colors.join(undefined)); // 打印结果:red,greeen,blue
// 传入指定字符串 +
console.log(colors.join('+')); // 打印结果:red+greeen+blue
// 传入空字符串 ""
console.log(colors.join('')); // 打印结果:redgreeenblue
// 数组中含有 undefined 和 null
console.log([undefined,2,null].join()); // 打印结果:,2,
2.3、concat(合并数组)
concat()
方法:用于合并两个或多个数组,返回一个新数组,原数组不会改变。- 如果原数组含有对象的引用,被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。
- 语法:
/*
valueN: 数组和/或值,将被合并到一个新的数组中。
*/
var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
// 描述
- 如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝
- 如果参数不是数组,则直接把他们添加到结果数组末尾
- 如果传入的是一个或多个数组,则concat()会把这些数组的每一项都添加到结果数组。
// 返回值
- 新的 Array 实例。
- 示例:
let colors = ['red','green','blue'];
// colors调用concat()方法,传入字符串‘yellow’ 和 一个包含‘bleak’和‘brown’的数组。
let colors2 = colors.concat('yellow',['bleak','brown']);
console.log(colors); //['red','green','blue']
console.log(colors2); //['red','green','blue','yellow','bleak','brown']
2.4、slice(拷贝数组)
-
slice()
方法:浅拷贝原数组,返回一个新数组,原数组不会改变。 -
如果原数组含有对象的引用,被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。
-
语法:
/*
begin: 可选,开始索引
end: 可选,结束索引
*/
arr.slice([begin[, end]])
// 描述
- 返回从 begin 到 end 对应的所有元素,不包含 end 对应的元素。
- 如果参数有负数,那么就以数组长度加上这个负值的结果来确定位置(length + value)
- 如果省略 begin,则 slice 从索引 0 开始。
- 如果 begin 超出原数组的索引范围,则会返回空数组。
- 如果 end 小于 begin ,则返回空数组。
- 如果 end 被省略,则 slice 会一直提取到原数组末尾。
- 如果 end 大于数组的长度,slice 也会一直提取到原数组末尾。
// 返回值
- 一个含有被提取元素的新数组。
- 示例:
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]
console.log(animals.slice(-2));
// expected output: Array ["duck", "elephant"]
console.log(animals.slice(2, -1));
// expected output: Array ["camel", "duck"]
console.log(animals.slice());
// expected output: Array ["ant", "bison", "camel", "duck", "elephant"]
三、ES5 新增方法
迭代方法
- ECMAScript为数组定义了5个迭代方法,这些方法都不会改变原数组。
- 每个方法接收两个参数:以每一项为参数运行的函数,以及可选的作为函数运行上下文的作用域对象(影响函数中this的值)
- 传递给每个方法的函数接收 3 个参数:
数组元素(item)
,元素索引(index)
和数组本身(array)
。- 因方法而异,这个函数的执行结果可能会也可能不会影响方法的返回值
3.1、filter(过滤数组)
filter()
:对数组的每一项都运行传入的函数,函数返回true项会组成数组返回。- 语法:
数组.filter(function (item,index,arr){});
- 返回值:根据我们的条件过滤出来的新数组
- 适合从数组中筛选满足给定条件的元素
let numbers = [1,2,3,4,5,4,3,2,1];
let filterResult = numbers.filter((item,index,array) => item > 2);
console.log(filterResult); //[3,4,5,4,3]
var arr[1,2,3,4,5];
var newArr = arr.filter(function(item,index,arr){
//函数内胆三个参数和 forEach 一样
//我们把我们的条件return 出去
return item > 2;
});
console.log(newArr); //[3,4,5]
- 等价于
var arr = [1,2,3,4,5];
var newArr = [];
for(var i = 0; i < arr.length; i++){
if(fn(arr[i],i,arr)){
newArr.push(arr[i]);
}
}
function fn(item,index,arr){
return item > 2;
}
consolo.log(newArr);
解析:
- 调用filter()返回的数组包含3,4,5,4,3,因为只有这些项传入的函数才返回 true
3.2、some(判断单项)
some()
:对数组的每一项都运行传入的函数,如果有一项
函数返回true,则返回 true
let numbers = [1,2,3,4,5,4,3,2,1];
let someResult = numbers.some((item,index,array) => item > 2);
console.log(someResult); //true
3.3、every(判断全部)
every()
:对数组的每一项都运行传入的函数,如果每一项
函数都返回 true,则返回 true
let numbers = [1,2,3,4,5,4,3,2,1];
let everyResult = numbers.every((item,index,array) => item > 2);
console.log(everyResult); //false
3.4、forEach(循环遍历)
forEach()
:对数组的每一项都运行传入的函数,没有返回值- 语法:
数组.forEach(function(item,index,arr){})
- 本质上,forEach()方法相当于使用for循环遍历数组
- forEach()的时候传递的那个函数,会根据数组的长度执行
- 数组的长度是多少,这个函数就会执行多少回
let numbers = [1,2,3,4,5,4,3,2,1];
let count=0;
numbers.forEach((item,index,array) =>{
count++;
})
console.log(count); //9
var arr = ['a','b','c'];
//forEach 就是将数组循环遍历,数组中有多少项,那么这个函数就执行多少回
arr.forEach(function(item,index,arr){
//在这个函数内部
//item就是数组红的每一项
//index 就是每一项对应的索引
//arr 就是原始数组
console.log(item);
console.log(index);
console.log(arr);
});
- 上面的代码就等价于
var arr = ['a','b','c'];
for(var i = 0; i < arr.length; i++){
fn(arr[i],i,arr);
}
function fn(item,index,arr){
console.log(item);
console.log(index);
console.log(arr);
}
3.5、map(遍历后返回)
map()
:对数组的每一项都运行传入的函数,返回由每次函数调用的结果构成的新数组。- 语法:
数组.map(function(item,index,arr){})
- 返回值:一个新的数组
- 这个方法非常适合创建一个与原数组一一对应的新数组。
- 和forEach类似,只不过可以对数组的每一项进行操作,返回一个新的数组
let numbers = [1,2,3,4,5,4,3,2,1];
//将数组的每一项都乘以2,并返回一个包含所有结果的新数组mapResult
let mapResult = numbers.map((item,index,array) => item*2);
console.log(mapResult); //[2, 4, 6, 8, 10, 8, 6, 4, 2]
var arr = ['a','b','c'];
// forEach 就是将数组循环遍历,数组中有多少项,那么这个函数就执行多少回
var newArr = arr.map(function(item,index,arr){
//函数里面的三个参数和 forEach 一样
//我们可以在这里操作数组中的每一项
//return 操作后的每一项
return item + '11';
})
console.log(newArr); // ["a11", "b11", "c11"]
- 上面代码等价于
var arr = ['a','b','c'];
var newArr = [];
for(var i = 0; i < arr.length; i++){
newArr.push(fn(arr[i],i,arr));
}
function fn(item,index,arr){
return item + '11';
}
console.log(newArr);// ["a11", "b11", "c11"]
3.6、reduce(归并数组值)
归并方法
- 归并方法都会迭代数组的所有项,并在此基础上构建一个最终返回值
- 每个方法接收两个参数:以每一项为参数运行的函数,以及可选的以之为并归起点的初始值
- 传给方法的函数接收4个参数:上一个并归值、当前项、当前项的索引、数组本身。
- 这个函数返回的任何值都会作为下一次调用同一个函数的第一个参数。
- 如果没有给这两个方法传入可选的第二个参数(作为归并起点值),则第一次迭代将从数组的第二项开始,因此传递给归并函数的第一个参数是数组的第一项,第二个参数是数组的第二项
reduce()
:从数组的第一项开始遍历到最后一项reduceRight()
:从数组的最后一项开始,遍历到第一项- 语法:
/*
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
5、initialValue:可选参数,函数迭代的初始值
*/
arr.reduce((prev,cur,index,array) => {},[initialValue])
不设置 initialValue
let values = [1,2,3];
//累加数组中所有的值
let sum = values.reduce((prev,cur,index,array) => {
console.log(prev,cur);
/*
左边是 prev,右边是 cur,由于没设置 initialValue,
所以第一次 prev = 数组第一项,cur = 数组第二项
1 2 ( prev + cur = 3 作为下一个 prev )
3 3 ( prev + cur = 6 cur是最后一个元素,所以到处结束,并返回最终结果 )
*/
return prev + cur
});
console.log(sum); // 6
设置 initialValue:
let values = [1,2,3];
//累加数组中所有的值
let sum = values.reduce((prev,cur,index,array) => {
console.log(prev,cur);
/*
左边是 prev,右边是 cur,由于设置了 initialValue,
所以第一次 prev = initialValue,cur = 数组第一项
11 1 ( prev + cur = 12 作为下一个 prev )
12 2 ( prev + cur = 14 作为下一个 prev )
14 3 ( prev + cur = 17 cur是最后一个元素,所以到处结束,并返回最终结果 )
*/
return prev + cur
}, 11);
console.log(sum); // 17
实例:
let values = ["name","age","gender"];
let enumMap = {
name: "流星",
age: 18,
gender: "男"
}
let newObj = values.reduce((obj, key) => {
console.log(obj,key);
/*
{} "name"
{name: '流星'} "age"
{name: '流星', age: 18} "gender"
*/
return { ...obj, [key]: enumMap[key] }
}, {})
console.log(newObj); // {name: '流星', age: 18, gender: '男'}
3.7、indexOf(直接查找索引)
搜索方法:
- ECMAScript提供两类搜索数组的方法:按严格搜索和按断言函数搜索
严格搜索:
- 接收两个参数:要查找的元素和一个可选的搜索位置
- 在比较第一个参数跟数组中的每一项时,会使用全等(===)比较,也就是说两项必须严格相等
-
indexOf()
:从数组前头向后搜索,返回要查找的元素在数组中的索引
,没找到则返回-1
-
lastIndexOf()
:从数组末尾向前搜索,搜索顺序与indexOf
相反,用法相同
let numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4)); //3
console.log(numbers.lastIndexOf(4)); //5
console.log(numbers.indexOf(4,4)); //5
console.log(numbers.lastIndexOf(4,4)); //3
let person = {name : 'jack'};
let people = [{name : 'jack'}];
let morePeople = [person];
console.log(people.indexOf(person)); //-1
console.log(morePeople.indexOf(person)); //0
四、ES6 新增方法
4.1、 find(函数查找元素)
搜索方法:
- ECMAScript提供两类搜索数组的方法:按严格搜索和按断言函数搜索
断言函数:
- 断言函数接收3个参数:元素、索引和数组本身。
- 元素表示数组中当前搜索的元素;索引是当前元素的索引;而数组就是正在搜索的数组。
- 断言函数返回真值,表示是否匹配。
-
find()
:返回数组中满足提供的测试函数的第一个元素
的值
(否则返回undefined
) -
语法:
array.find((element,index,array)=>{
// element: 必选,当前遍历到的元素
// index: 可选,当前遍历到的索引
// array: 可选,数组本身
// 找到后直接返回,不再继续向下搜索
return '判断条件'
})
- 示例 1:查找数组中对象的属性
// 定义一个数组
const people =[
{
name : '张三',
age : 88
},
{
name : '李四',
age : 64
}
];
// 定义一个 callback 函数
function callBackName(element) {
return element.name === '张三';
}
// 不改变原数组
let findValue = people.find(callBackName)
console.log(findValue); // { name: '张三', age: 88 }
// 一步搞定写法:
let findValue2 = people.find((elemet,index,array) => elemet.age > 18)
console.log(findValue2); // { name: '张三', age: 88 }
- 示例 2:运行过程
const evens = [2,4,6];
evens.find((element,index,array) =>{
console.log(element); //打印遍历到的元素
console.log(index); //打印遍历到元素的索引
console.log(array) //打印数组本身
return element === 4; //查找数组中与4相匹配的元素,找到后终止函数
});
//第一次遍历
/*
2
0
[2,4,6]
*/
//第二次遍历
/*
4
1
[2,4,6]
*/
//由于第二次已经找到4,所以不用在继续搜索下去
4.2、findIndex(函数查找索引)
findIndex()
:返回数组中满足提供的测试函数的第一个元素
的索引
(否则返回-1
)- 语法:
array.findIndex((element,index,array)=>{
// element: 必选,当前遍历到的元素
// index: 可选,当前遍历到的索引
// array: 可选,数组本身
// 找到后直接返回,不再继续向下搜索
return '判断条件'
})
- 示例 1:查找数组中对象的属性
// 定义一个数组
const people =[
{
name : '张三',
age : 88
},
{
name : '李四',
age : 64
}
];
// 定义一个 callback 函数
function callBackName(element) {
return element.name === '张三';
}
// 不改变原数组
let findIndexValue = people.findIndex(callBackName)
console.log(findIndexValue); // 0
// 一步搞定写法:
let findIndexValue2 = people.findIndex((elemet,index,array) => elemet.age > 18)
console.log(findIndexValue2); // 0
4.3、fill(填充值)
fill()
:可以像一个已有的数组中插入全部或者部分相同的的值。
- 开始索引用于指定开始的位置,他是可选的。
- 如果不提供结束索引,则一直填充到数组末尾
- 负值索引从数组末尾开始结束,相当于数组长度+负索引=一个正索引
- 包含开始索引,不包含结束索引
const zeroes = [0,0,0,0,0] //length = 5
//用 5 填充整个数组
zeroes.fill(5);
console.log(zeroes); //[5,5,5,5,5]
zeroes.fill(0); //重置数组归0
//用 6 填充索引大于等于 3 的元素
zeroes.fill(6,3);
console.log(zeroes); //[0,0,0,6,6]
zeroes.fill(0); //重置数组归0
//用 7 填充索引大于等于 1 且小于 3 的元素
zeroes.fill(7,1,3);
console.log(zeroes); //[0,7,7,0,0]
zeroes.fill(0); //重置数组归0
//用 7 填充索引大于等于 1 且小于 3 的元素
zeroes.fill(7,-4,-2); //length-4=1,length-2=3
console.log(zeroes); //[0,7,7,0,0]
zeroes.fill(0); //重置数组归0
- 静默忽略超出数组边界、0长度即方向相反的索引范围
const zeroes = [0,0,0,0,0] //length = 5
//索引过低,忽略
zeroes.fill(1,-10,-6);
console.log(zeroes); //[0,0,0,0,0]
//索引过高,忽略
zeroes.fill(1,10,16);
console.log(zeroes); //[0,0,0,0,0]
//索引反向,忽略
zeroes.fill(1,10,6);
console.log(zeroes); //[0,0,0,0,0]
//索引部分可用,填充可用索引
zeroes.fill(1,3,10);
console.log(zeroes); //[0,0,0,1,1]
4.4、copyWithin(复制后插入)
copyWithin()
:按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置。- 在原索引或目标索引到达数组边界时停止
- 包含开始索引,不包含结束索引
let ints;
//创建箭头函数reset()给ints赋值。
let reset = () => ints = [0,1,2,3,4,5,6,7,8,9];
reset();
//从ints中复制索引 0 开始的位置,插入到索引 5 开始的位置
ints.copyWithin(5);
console.log(ints); //[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
reset(); //重置ints数组值
//从ints中复制索引 5 开始的位置,插入到索引 0 开始的位置
ints.copyWithin(0,5);
console.log(ints); //[5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
reset(); //重置ints数组值
//从ints中复制索引 0 到 3 结束的位置位置,插入到索引 4 开始的位置
ints.copyWithin(4,0,3);
console.log(ints); //[0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
reset(); //重置ints数组值
//js引擎在插值前会完整复制范围内的值,因此复制期间不存在重写的风险
ints.copyWithin(2,0,6);
console.log(ints); //[0, 1, 0, 1, 2, 3, 4, 5, 8, 9]
reset(); //重置ints数组值
//支持负索引,与fill()计算方法一样
ints.copyWithin(-4,-7,-3); //length = 10,等价于:(6,3,7)
console.log(ints); //[0, 1, 2, 3, 4, 5, 3, 4, 5, 6]
reset(); //重置ints数组值
- 静默忽略超出数组边界、0长度即方向相反的索引范围
与fill类似,再此不再重复讲解
4.5、 迭代器 keys()、values()、entries()
迭代器方法,在ES6中,Array的原型上暴露了 3 个用于检索数组内容的方法
keys()
:返回数组索引的迭代器。values()
:返回数组元素的迭代器。entries()
:返回(索引/值)键值对的迭代器
const a = ['foo','bar','baz','qux'];
const aKeys = (a.keys());
const aValues = (a.values());
const aEntries = (a.entries());
console.log(aKeys); //Array Iterator {}
console.log(aValues); //Array Iterator {}
console.log(aEntries); //Array Iterator {}
/*因为这些方法都返回迭代器,所以可以将它们的内容
通过Array.from()直接转换为数组实例*/
console.log('通过Array.from()转换后的返回值');
console.log(Array.from(aKeys)); //[0, 1, 2, 3]
console.log(Array.from(aValues)); //["foo", "bar", "baz", "qux"]
console.log(Array.from(aEntries)); //[[0, "foo"],[1, "bar"],[2, "baz"],[3, "qux"]]
- 使用ES6解构可以非常容易的在循环中拆分键值对:
const a = ['foo','bar','baz','qux'];
//for-of循环是一种严格的迭代语句,用于遍历可迭代对象的元素
for(const [idenx,element] of a.entries()){
console.log(idenx);
console.log(element);
}
// 0
// foo
// 1
// bar
// 2
// baz
// 3
// qux
五、ES+ 新增方法
5.1、 includes(是否存在)ES2016
includes()
:es7新增,表示是否找到一个与指定元素匹配的项,但它返回布尔值,严格相等(===)
let numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.includes(4)); //true
console.log(numbers.includes(4,7)); //false
let person = {name : 'jack'};
let people = [{name : 'jack'}];
let morePeople = [person];
console.log(people.includes(person)); //false
console.log(morePeople.includes(person)); //true
5.2、 flat(数组降维)ES2019
flat()
方法:会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回- 语法:
/*
depth: 指定要提取嵌套数组的结构深度,默认值为 1,使用 Infinity,可展开任意深度的嵌套数组
*/
var newArray = arr.flat([depth])
/* 返回值 */
一个包含将数组与子数组中所有元素的新数组
- 示例:扁平化嵌套数组
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- 示例:扁平化与数组空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
5.3、 flatMap(循环降维)ES2022
-
flatMap()
方法:使用映射函数映射每个元素,然后将结果压缩成一个新数组(相当于map()
+ 返回值组成的数组执行flat()
方法) -
语法:
/*
currentValue: 当前正在数组中处理的元素。
index:可选的,数组中正在处理的当前元素的索引
array:可选的,被调用的 map 数组
thisArg:可选的,执行 callback 函数时 使用的this 值
*/
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
/* 返回值 */
一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 depth 值为 1
- 示例:与map相比较
var arr1 = [1, 2, 3, 4];
arr1.map(x => [x * 2]);
// [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
// 只能展开一层数组
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]
- 示例:与map的区别
let arr1 = ["it's Sunny in", "", "California"];
arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]
六、静态方法
6.1、Array.of(创建数组)
Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
6.2、Array.from()(拷贝迭代数组)
Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
6.3、Array.isArray(判断是不是数组)
Array.isArray() 用于确定传递的值是否是一个 Array。
Array.isArray([1, 2, 3]);
// true
Array.isArray({foo: 123});
// false
Array.isArray("foobar");
// false
Array.isArray(undefined);
// false
其他资料:数组基础知识