欢迎来到好多视频第238期,来用函数式编程的思路实现一下数组筛选功能,过程中代码会不断迭代,一起来看看函数式编程有什么特点,用了它有什么好处。
先用最朴素的循环思路,实现一下筛选。
const users = [
{
name: 'peter',
gender: 'male'
},
{
name: 'billie',
gender: 'female'
}
]
let arr = []
for (let i = 0; i < users.length; i++) {
if (users[i].gender === 'female') arr.push(users[i])
}
console.log(arr)
创建 index.js 文件,咱们要处理的数据就是 users ,是一个对象数组,每个对象中包含姓名和性别。
下面我要把数组中的女性筛选出来,先定义一个空数组。从 i = 0 开始迭代,把每一个数组元素都拿出来,判断他的性别是不是女性,如果是,就 push 到空数组中。
最后把数组打印出来。
到终端中,运行 node index.js
可以看到打印出的数组中只保留了女性。
下面来用函数式编程的思路重构这个效果。函数式编程的基本原则就是,所有的东西都封装到函数里。这里的函数可不是任意的,必须是纯函数,应该只受到输入,也就是参数的值,的影响,同时也只关注自己要输出的内容,也就是 return 的值。
其他的事情一概不做,例如生成各种副作用,比如打印信息啦,保存数据啦,发送网络请求啦,同时也不能修改传入的参数,
Array.prototype.myFilter = function (callback) {
arr = []
for (let i = 0; i < this.length; i++) {
if (callback(this[i]))
arr.push(this[i])
}
return arr
}
const female = users.myFilter(user => {
return user.gender === 'female'
})
console.log(female)
数组的 prototype 里添加一个 myFilter 函数,filter 的中文意思是筛选。把原有的迭代逻辑封装起来, users 替换为 this 所指代的当前数组。
然后把 if 括号中的判断逻辑抽出到 callback 函数中。
这里 myFilter 是一个所谓的高阶函数,因为他会把其他的函数作为自己的参数。而作为人家的参数的函数就被称为回调函数,也就是 callback 。
myFilter 里面传入一个回调函数,还记得咱们前面说的,回调函数的输出要保证只收到它的输入,也就是参数的影响,同时一定要 return 东西,这里就是根据用户性别是不是女性来返回 true 或者 false 。
终端中,运行 node index.js
发现依然是能正确输出的。
逻辑拆分的好处是便于维护和测试,同时也更方便的复用代码。
const isFemale = user => user.gender === 'female'
const female = users.myFilter(isFemale)
在 JS 中,function 也是一个 value ,可以赋值到变量中。来把回调函数抽出,赋值给 isFemale 。
终端中,测试一下,发现依然管用。
也可以再定义 isMale 函数。打印出所有男性同胞。改成判断 isMale ,发现一样好用。
这里的实现的效果是如此的常用,以至于 JS 已经原生集成了 filter 方法。改成原生的 filter 函数,运行结果没有任何的区别。