filter
let newArray = arr.filter(callback(element[, index[, array])[, thisArg])
- callback
-
- 用来测试数组的每个元素的函数。返回
true表示该元素通过测试,保留该元素,false则不保留 - 接收以下三个参数
element-
- 数组中当前正在处理的元素
index可选-
- 当前正在被处理元素在数组中的索引
array可选-
- 调用filter的数组本身
- 用来测试数组的每个元素的函数。返回
thisArg可选-
- 当传入此值时,callback函数内部的this绑定thisArg
描述
filter对每个元素调用一次callback,然后对callback的返回值进行筛选,留下 !!returnValue === true的元素,生成新的数组,void返回值为undefined
对于thisArg
当callback是箭头函数时无法绑定thisArg,是function声明时可以绑定。箭头函数没有this,绑定不了
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const obj = {
name: '小明',
age: 8
}
const newArray = array.filter(function(item) {
return item === this.age
}, obj)
console.log(newArray) // [ 8 ]
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const obj = {
name: '小明',
age: 8
}
const newArray = array.filter((item) => {
console.log(this)
return item === this.age
}, obj)
console.log(newArray) // 空数组
//{}
//{}
//{}
//{}
//{}
//{}
//{}
//{}
//{}
//[]
手动实现
const newFilter = (array, callback, thisArg = {}) => {
if (!/^[Ff]unction$/.test(typeof callback)) {
console.log('这不是一个函数');
throw new Error();
}
if (!array) return [];
let newObject = {...thisArg};
newObject.filterr = function (array2) {
let newArray = [];
for (let index in array2) {
let returnValue = callback(array2[index], index, array2);
if (!!returnValue) newArray.push(array2[index])
}
return newArray
}
return newObject.filterr(array)
}
let array = newFilter([1, 2, 3, 4, 5], (item) => {
return item > 3
}, { name: '小明'})
console.log(array) // [4, 5]
搞得这么复杂是想将箭头函数的this指向解决,但是最终还是没有解决
map
map与filter原理一致,对数组中每一个元素调用一下callback,传入元素经过callback后返回出新的元素,最终生成一个新的数组
手动实现
function newMap (array, callback, thisArg = {}) {
if (!/^[Ff]unction$/.test(typeof callback)) {
console.log('这不是一个函数');
throw new Error();
}
if (!array) return [];
let newArray = [];
for (let index in array) {
let returnValue = callback.call(thisArg, array[index], index, array);
newArray.push(returnValue)
}
return newArray
}
let array = newMap([1, 2, 3, 4, 5], function (item) {
return item + 3
}, { name: '小明'})
console.log(array)
聊一聊 async 修饰的回调函数
为什么filter的被async修饰过的回调函数无法生效
首先
arr = [1, 2, 3]
然后arr调用filter
arr.filter(async (item) => item >=2 )
因为async修饰的函数返回值只会是一个promise
如果没有被async修饰,原本应该是这样的:
let newArr = (return [false, true, true])
// 小括号表示函数及函数体,return 筛选出数组中是true的,最后结果是[2, 3]
但是被async修饰之后,结果是这样的
let newArr = (return [Promise<pending>, Promise<pending>, Promise<pending>])
// 因为没有具体的布尔值,会对元素进行两次取反操作,即!!Propise<pending>,结果为true
// 于是结果就是 [1, 2, 3],与原数组一致
那为什么map可以使用异步函数作为回调呢
因为map是映射不是过滤,他不需要对回调函数的返回值进行处理,是啥样就是啥样给出去
arr.map(async (item) => item + 2 )
之前的步骤是一样的,到了读取返回值的时候,是这样的
let newArr = (return [Promise<pending>, Promise<pending>, Promise<pending>])
// newArr 就是一个元素全为Promise的数组
// newArr == [Promise<pending>, Promise<pending>, Promise<pending>]
在newArr前使用一个先使用promise.all()同时对每一个元素同时进行处理(有点像归一化?),只剩一个promise,然后在Promise.all前使用一个await,等待最后的这个Promise执行结束
let newArr = await Promise.all(return [Promise<1>, Promise<2>, Promise<3>])
// newArr = [3, 4, 5]