01-for和forEach
-
for循环是最常规最通用的一种循环遍历方法;
-
forEach方法是一个高阶函数,会引入额外的函数调用开销,forEach会改变原数组;
1.性能上的比较
for>forEach
-
for循环直接操作索引,没有额外的函数调用和上下文,所以性能是最快的
-
for可以使用break终止,forEach不支持跳出循环
尝试分别用for
和forEach
循环遍历数量级比较大的数组,for
循环用时小于``forEach
的执行时间。
// 定义一个数量级比较大的数组
let arrs = [...Array(9999999).keys()];
let total = 0;
let startTime = Date.now();
for (let i = 0; i < arrs.length; i++) total += i;
let endTime = Date.now();
let countTime = endTime - startTime;
console.log('计数---->' + total); //计数---->49999985000001
console.log('消耗时间---->' + countTime); //消耗时间---->127
// 定义一个数量级比较大的数组
let arrs = [...Array(9999999).keys()];
let total = 0;
let startTime = Date.now();
arrs.forEach((item) => (total += item));
let endTime = Date.now();
let countTime = endTime - startTime;
console.log('计数---->' + total); //计数---->49999985000001
console.log('消耗时间---->' + countTime); //消耗时间---->267
2.异步同步化的支持度
forEach
函数内,不支持await异步等待。
如下案例,使用forEach
模拟异步请求时,获取结果为空数组
let arrs = [1, 2, 3];
let datas = [];
function fetchData() {
arrs.forEach(async (item) => {
const { data } = await uni.request({
url: 'http://jsonplaceholder.typicode.com/posts/' + item
});
datas.push(data);
});
console.log(datas); // []
}
fetchData();
该用for
循环后,可以获取对应的三条数据
let arrs = [1, 2, 3];
let datas = [];
async function fetchData() {
for (let i = 0; i < arrs.length; i++) {
const { data } = await uni.request({
url: 'http://jsonplaceholder.typicode.com/posts/' + arrs[i]
});
datas.push(data);
}
console.log(datas); // [{...},{...},{...}]
}
fetchData();
02-map方法
map()
方法是数组原型的一个函数,数组遍历不破坏原数组,将会创建一个新数组,按照原始数组元素顺序依次执行给定的函数。
map()
方法非常适合用于处理数组中的每个元素并生成新的数组。
1.语法
-
map(callbackFn)
-
map(callbackFn,thisArg)
1.参数callbackFn
为数组中的每个元素执行的函数。它的返回值作为一个元素被添加为新数组中。该函数被调用时将传入以下参数:
element
:数组中当前正在处理的元素。
index
:正在处理的元素在数组中的索引。
array
:调用了 map()
的数组本身。
2.参数thisArg
(可选)
执行 callbackFn
时用作 this
的值。
2.用法
1.将数组中的每个元素x2
获取新数组
let arrs = [1, 2, 3, 4, 5];
let newArrs = arrs.map((item) => item * 2);
console.log(newArrs); // [2, 4, 6, 8, 10]
console.log(arrs); // [1, 2, 3, 4, 5]
2.获取数组中的名字,并保存到新数组中
let arrs = [
{
name: '电脑',
price: 12999
},
{
name: '手机',
price: 8499
},
{
name: '平板',
price: 5299
}
];
let newArrs = arrs.map((item) => {
return item.name;
});
console.log(newArrs); // ['电脑', '手机', '平板']
3.修改数组中的价格,并新增number属性
写入的price属性,如果原来有,会覆盖原有的
let arrs = [
{
name: '电脑',
price: 12999
},
{
name: '手机',
price: 8499
},
{
name: '平板',
price: 5299
}
];
let newArrs = arrs.map((item) => {
return {
...item,
price: item.price + 100,
number: 1000
};
});
console.log(newArrs);
4.修改数组中的属性名,并可通过解构的写法
let arrs = [
{
key: 1,
content: '电脑'
},
{
key: 2,
content: '手机'
},
{
key: 3,
content: '平板'
}
];
let newArrs = arrs.map((item) => {
return {
id: item.key,
text: item.content
};
});
console.log(newArrs);
// [
// {
// key: 1,
// content: '电脑'
// },
// {
// key: 2,
// content: '手机'
// },
// {
// key: 3,
// content: '平板'
// }
// ];
通过解构的方式,把item解构成对应的值更直观
let arrs = [
{
key: 1,
content: '电脑'
},
{
key: 2,
content: '手机'
},
{
key: 3,
content: '平板'
}
];
let newArrs = arrs.map(({ key, content }) => {
return {
id: key,
text: content
};
});
console.log(newArrs);
5.异步请求测试
network请求的状况,会同时发送请求,会节省很多的时间
let arrs = [1, 2, 3];
let datas = arrs.map(async (item) => {
let res = await uni.request({
url: 'http://jsonplaceholder.typicode.com/posts/' + item
});
return res;
});
console.log(datas); // [Promise, Promise, Promise]
Promise.all(datas).then((res) => {
console.log(res);
});
03-filter方法
filter()
过滤方法,会对原数组中的每个元素应用指定的函数,并返回一个新数组,其中包含符合条件的元素。原数组不会受到影响。
1.语法
和map
语法相似
-
fliter(callbackFn)
-
filter(callbackFn,thisArg)
1.参数callbackFn
为数组中的每个元素执行的函数。它的返回值作为一个元素被添加为新数组中。该函数被调用时将传入以下参数: element
:数组中当前正在处理的元素。 index
:正在处理的元素在数组中的索引。 array
:调用了 filter()
的数组本身。
2.参数thisArg
(可选) 执行 callbackFn
时用作 this 的值。
2.用法
1.在filter
回调函数中,满足true即可被处理到新函数中,false不做处理。
let arrs = [1, 5, 2, 8, 10];
let newArrs = arrs.filter((item) => {
return false;
});
console.log(newArrs); // true [1, 5, 2, 8, 10] false []
2.返回一个年龄大于30的数组
let arrs = [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 28
},
{
name: '王二',
age: 30
},
{
name: '赵五',
age: 38
},
{
name: '孙六',
age: 32
}
];
let newArrs = arrs.filter((item) => {
return item.age > 30;
});
console.log(newArrs);
// [
// {
// name: '赵五',
// age: 38
// },
// {
// name: '孙六',
// age: 32
// }
// ];
3.配合indexOf进行数组去重
首先,indexOf()
方法返回的是查找的第一个符合的元素的下标
let arrs = [1, 5, 2, 8, 2, 5, 9];
console.log(arrs.indexOf(5)); // 找到第一个符合的元素5,返回索引值 1
然后,配合filter()
方法实现数组去重
let arrs = [1, 5, 2, 8, 2, 5, 9];
let newArrs = arrs.filter((item, index, self) => {
return self.indexOf(item) === index;
});
console.log(newArrs); // [1, 5, 2, 8, 9]
4.filter和map方法实现链式调用
先用filter()
方法处理数据,然后在调用map()
方法处理
let arrs = [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 28
},
{
name: '王二',
age: 30
},
{
name: '赵五',
age: 38
},
{
name: '孙六',
age: 32
}
];
let newArrs = arrs
.filter((item) => {
return item.age > 30;
})
.map((item) => {
return {
...item,
des: '大龄程序员'
};
});
console.log(newArrs);
04-reduce方法
**reduce()**
方法对数组中的每个元素按序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
1.语法
-
reduce(callbackFn)
-
reduce(callbackFn,initialValue)
1.参数callbackFn
为数组中每个元素执行的函数。其返回值将作为下一次调用 callbackFn
时的 accumulator
参数。对于最后一次调用,返回值将作为 reduce()
的返回值。该函数被调用时将传入以下参数:
-
prev
(必填),上一次调用 callbackFn 的结果。 -
current
(必填),当前元素的值。 -
index
(可选),current 在数组中的索引位置。 -
array
(可选),调用了reduce() 的数组本身。
2.参数initialValue
第一次调用回调时初始化 accumulator
的值。如果指定了 initialValue
,则 callbackFn
从数组中的第一个值作为 currentValue
开始执行。如果没有指定 initialValue
,则 accumulator
初始化为数组中的第一个值,并且 callbackFn
从数组中的第二个值作为 currentValue
开始执行。在这种情况下,如果数组为空(没有第一个值可以作为 accumulator
返回),则会抛出错误。
2.用法
1.简单的求和或求积
如果没有定义初始值,那么prev就默认数组第一个值,current为第二个值,切循环执行了四次
let arrs = [1, 2, 3, 4, 5];
arrs.reduce((prev, current, index) => {
console.log(prev, current, index);
});
如果默认传入初始值,则循环从第一个开始
let arrs = [1, 2, 3, 4, 5];
let result = arrs.reduce((prev, current, index) => {
return prev + current;
}, 0);
console.log(result); // 15
稍微复杂点的求和
// 对年龄求和
let arrs = [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 28
},
{
name: '王二',
age: 30
},
{
name: '赵五',
age: 38
},
{
name: '孙六',
age: 32
}
];
let result = arrs.reduce((prev, current, index) => {
return prev + current.age;
}, 0);
console.log(result); // 146
2.求最大值或最小值
let arrs = [18, 25, 10, 58, 26];
let result = arrs.reduce((prev, current) => {
return Math.max(prev, current);
}, 0);
console.log(result);// 58
05-every和some方法
every()
方法只有所有数据都满足条件才会返回true
,而some()
方法只有有一个数据满足条件就返回true
.
一.every方法
**every()**
方法测试一个数组内的所有元素是否都能通过指定函数的测试。它返回一个布尔值。
1.语法
-
every(callbackFn)
-
every(callbackFn,thisArg)
1.参数callbackFn
-
element
:数组中当前正在处理的元素。 -
index
: 正在处理的元素在数组中的索引。 -
array
:调用了 every() 的数组本身。
2.参数thisArg
-
执行
callbackFn
时用作 this 的值。
2.用法
通过判断数组中的数值是否大于10,只有当所有的数值都大于10的时候,参会返回true
,否则返回false
let arrs = [15, 10, 5, 100];
let result = arrs.every((item) => item > 10);
console.log(result); // false
二.some方法
**some()**
方法测试数组中是否至少有一个元素通过了由提供的函数实现的测试。如果在数组中找到一个元素使得提供的函数返回 true,则返回 true;否则返回 false。它不会修改数组。
语法和用法同上
只要有一个条件满足,就直接返回true
let arrs = [15, 10, 5, 100];
let result = arrs.some((item) => item > 10);
console.log(result); // true
06-includes包含方法
**includes()**
方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true
,否则返回 false
。
1.语法
-
includes(searchElement)
-
includes(searchElement,fromIndex)
1.searchElement
参数
需要查找的值。
2.fromIndex
参数(可选)
几乎不用。开始搜索的索引(从零开始),会转换为整数。
2.用法
判断某个数字是否包含在数组内
const arrs = [1, 2, 3, 4, 5];
console.log(arrs.includes(5)); // true
console.log(arrs.includes(8)); // false
只能判断某个值,像下面的情况为false
const arr = [1, 2, 3, 4, 5, [6, 7]];
console.log(arrs.includes(5)); // true
console.log(arrs.includes([6, 7])); // false
配合every
方法,实现判断某个数组是否包含在另一个数组中
const arrs = [18, 2, 9, 6, 8];
const arrs2 = [18, 2, 9];
const arrs3 = [18, 2, 20];
let isIncludes = arrs2.every((item) => {
return arrs.includes(item);
});
console.log(isIncludes); // true
let isIncludes2 = arrs3.every((item) => arrs.includes(item));
console.log(isIncludes2); // false
07-其他常用方法
1.concat
**concat()**
方法用于合并两个或多个数组。此方法不会改变原数组,而是返回一个新数组。
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6, 7];
console.log(arr1.concat(arr2)); // [1, 2, 3, 4, 5, 6, 7]
2.find
**find()**
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined 。
let arr1 = [10, 20, 30, 40];
let result = arr1.find((item) => {
return item > 20;
});
console.log(result); // 30
3.findIndex
**findIndex(**
) 方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
let arr1 = [10, 20, 30, 40];
let result = arr1.findIndex((item) => {
return item > 20;
});
console.log(result); // 2
4.indexOf
**indexOf()**
方法返回在数组中可以找到一个给定元素的**第一个索引,如果不存在,则返回-1**。 (通常用它判断数组中有没有这个元素)
let arr1 = [10, 20, 30, 40, 20];
let result = arr1.indexOf(20);
let result2 = arr1.indexOf(120);
console.log(result); // 返回索引值:1
console.log(result2); // -1
5.join
**join()**
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。 如果数组只有一个项目,那么将返回该项目而不使用分隔符。
可自定义分隔符,默认为,
let arr1 = [10, 20, 30, 40, 20];
let result = arr1.join();
console.log(result); // 10,20,30,40,20
let result2 = arr1.join('-');
console.log(result2); // 10-20-30-40-20
6.pop
**pop()**
方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度,改变原数组。
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.pop();
console.log(result); // 50
console.log(arr1); // [10, 20, 30, 40];
7.push
**push()**
方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度,改变原数组。
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.push(60);
console.log(result); // 6,返回数组长度
console.log(arr1); // [10, 20, 30, 40, 50,60]
arr1.push(70, 80);
console.log(arr1); // [10, 20, 30, 40, 50,60,70, 80]
8.shift
**shift()**
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度,改变原数组。
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.shift();
console.log(result); // 10
console.log(arr1); // [ 20, 30, 40, 50,60]
9.unshift
**unshift()**
方法将一个或多个元素添加到数组的开头,并返回该数组的新长度,改变原数组。
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.unshift(60, 70);
console.log(result); // 7
console.log(arr1); // [ 60, 70,20, 30, 40, 50]
10.splice
**splice()**
方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。
由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
1.删除一个数值
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.splice(2, 1); // 索引2处,删除一个元素,即删除30
console.log(result); // [30],返回删除的数组
console.log(arr1); // 原数组也发生变化
2.删除并在原处新增一个数值
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.splice(2, 1, '修改'); // 索引2处,删除一个
console.log(result); // [30],返回删除的数组
console.log(arr1); // 原数组也发生变化 [10, 20, '修改', 40, 50]
3.索引新增一个元素
let arr1 = [10, 20, 30, 40, 50];
let result = arr1.splice(2, 0, '新增'); // 索引2处,新增
console.log(result); // [],返回删除的数组
console.log(arr1); // 原数组也发生变化 [10, 20, '修改',30, 40, 50]
11.slice
**slice()**
方法返回一个新的数组对象,这一对象是一个由 start
和 end
决定的原数组的浅拷贝(包括 start
,不包括 end
),其中 start
和 end
代表了数组元素的索引。原始数组不会被改变。
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
// 返回从索引2到结尾的元素
console.log(animals.slice(2));
// Expected output: Array ["camel", "duck", "elephant"]
// 返回索引从2到4的元素,但包含4
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"]
12.reverse
**reverse()**
方法将数组中元素的位置颠倒,并返回该数组。该方法会改变原数组。
let arr1 = [5, 3, 1, 8, 6];
console.log(arr1.reverse()); // [6, 8, 1, 3, 5]
console.log(arr1); // [6, 8, 1, 3, 5]
13.sort
**sort()**
let arr1 = [5, 3, 1, 8, 6, 11];
console.log(arr1.sort()); // [1, 11, 3, 5, 6, 8]
console.log(arr1); // [1, 11, 3, 5, 6, 8]