2024年最全函数式编程之高阶函数(1),最新美团点评Web前端团队面试题

最后

由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

3.3 真实的高阶函数

上一节我们写了几个简单的高阶函数,这一节我们将了解真实的高阶函数, 并从简单的高阶函数开始,逐步进入复杂的高阶函数,这些函数都是 JavaScript 开发者日常中会用到的。

3.3.1 every 函数

我们经常需要检查数组的内容是否为数字,数组或其他类型,一般情况下,我们编写典型的循环方法来解决这个问题。但是,下面将这些抽象到一个 every 函数中,它接收两个参数:一个数组和一个函数,它使用传入的函数检查数组的所有元素是否为 true,其实就是数组的 every 方法

`// es6-functional.js

const every = (arr, fn) => {

let result = true;

for(let i = 0,len = arr.length; i < len; i++){

result = result && fn(arr[i])

}

return result;

}`

在此处,我们简单的遍历传入的数组,并使用当前遍历的数组元素内容调用 fn。注意传入的 fn 需要返回一个布尔值。然后我们用 && 运算确保所有的数组内容遵循 fn 给出的条件。

让我们测试一下,传入一个 NaN 数组,isNaN 作为 fn 传入,他会检查给定的数字是否为 NaN

`every([NaN,NaN,NaN], isNaN)

// true

every([NaN,NaN,4], isNaN)

// false`

every 函数是一个典型的高阶函数,实现简单而且非常有用。在继续之前,我们需要了解一下 for…of 循环,它是 ES6 规范的一个部分,用于遍历数组元素,下面用 for … of 循环重写 every 函数

`// es6-functional.js

const every = (arr, fn) => {

let result = true;

for(const value of arr){

result = result && fn(value)

}

return result;

}`

for…of 也是旧的 for(…) 循环的抽象,通过隐藏索引变量移除了对数组的遍历。我们使用 every 抽象出了 for…of,这就是抽象。如果下一个版本的 JavaScript 改变了 for…of 的使用方式,我们只需在 every 函数中修改,这就是抽象函数最大的好处。

3.3.2 some 函数

与 every 函数类似,还有一个 some 函数,也是数组的一个方法,some 函数的工作方式和 every 相反,只要数组中的任意一个元素通过传入的函数返回 true,some 函数就将返回 true。some 函数也被称为 any 函数。为实现some 函数,我们需要使用 || 而不是 &&,具体代码如下

`// es6-functional.js

const some = (arr,fn) => {

let result = false;

for(const value of arr){

result = result||fn(value)

}

return result;

}`

注意:这里的 some 和 every 函数都是低效的实现。every 应该在遇到第一个不匹配的元素时就停止遍历数组,some 应该在遇到第一个匹配的元素时就停止遍历数组,在这里只是为了理解高阶函数的概念,而不是为了编写高效的代码

有了 some 函数,就可以通过传入如下数组检验一下结果

`some([NaN,NaN,4], isNaN)

// true

some([3,4,4], isNaN)

// false`

了解了 some 和 every 是如何工作的,下面来看看 sort 函数以及高阶函数如何在其中使用的。

3.3.3 sort 函数

sort 函数是 Array 原型的内置函数。假设我们需要给一个水果列表排序:

var fruit = ['cherries','apples','bananas'];

你可以简单地调用 sort 函数

`fruit.sort();

// [‘apples’,‘bananas’,‘cherries’];`

它还可以接受一个 compare 函数,如果未提供的话,则会按照 unicode 编码顺序排序。我们可以通过自己提供的 compare 函数来排序任何 JavaScript 数据。sort 函数灵活的原因要归功于高阶函数的本质!

在编写 compare 函数之前,我们先看看它实际上应该实现什么

`function compare(a, b){

if(/* 根据某种排序标准 a < b */){

return -1;

}

if(/* 根据某种排序标准 a > b */){

return 1;

}

return 0;

}`

举个简单的例子,假设我们有一个人员列表

`var people = {

{firstname: “aaFirstName”, lastname: “cclastName”},

{firstname: “ccFirstName”, lastname: “aalastName”},

{firstname: “bbFirstName”, lastname: “bblastName”},

}`

现在需要使用对象中的 firstname 键对人员进行排序,以如下形式传入 compare

`people.sort((a,b) => {

return (a.firstname < b.firstname) ? -1:(a.firstname > b.firstname) ? 1:0

/*

if(a.firstname < b.firstname){

return -1;

}else if(a.firstname > b.firstname){

return 1

}else{

return 0

}

*/

})`

上面的代码将返回如下数据

`[

{ firstname: ‘aaFirstName’,lastName: ‘cclastName’},

{ firstname: ‘bbFirstName’,lastName: ‘bblastName’},

{ firstname: ‘ccFirstName’,lastName: ‘aalastName’},

]`

根据 lastname 的排序如下

`people.sort((a,b) => {

return (a.lastname < b.lastname) ? -1:(a.lastname > b.lastname) ? 1:0

/*

if(a.lastname < b.lastname){

return -1;

}else if(a.lastname > b.lastname){

return 1

}else{

return 0

}

*/

})`

它将返回

`[

{ firstname: ‘ccFirstName’,lastName: ‘aalastName’},

{ firstname: ‘bbFirstName’,lastName: ‘bblastName’},

{ firstname: ‘aaFirstName’,lastName: ‘cclastName’},

]`

我们在看一下 compare 函数的逻辑

`function compare(a, b){

if(/* 根据某种排序标准 a < b */){

return -1;

}

if(/* 根据某种排序标准 a > b */){

return 1;

}

return 0;

}`

知道了 compare 函数的算法,我们能做得更好些吗?能把上面的逻辑抽象到一个函数中去吗?从上面的例子可以看到,我们用几乎重复的代码编写了两个函数去比较 firstname 和 lastname。我们将要设计的函数不会以函数Wie参数,但是会返回一个函数。

下面调用函数 sortBy,它允许用户基于传入的属性对对象数组排序,代码如下

`// es6-functional.js

const sortBy = (property) => {

// 返回一个函数

return (a,b) => {

var result = (a[property] < b[property]) ? -1:(a[property] > b[property]) ? 1:0

return result;

/*

if(a[property] < b[property]){

return -1;

}else if(a[property] > b[property]){

return 1

}else{

return 0

}

*/

}

}`

sortBy 函数接受一个名为 property 的参数并返回一个接受两个参数的新函数

返回函数清晰的描述了 compare 函数的逻辑

假设我们使用属性名 firstname 调用函数,函数体将替换 property 参数,如下所示

(a, b) => return (a['firstname'] < b['firstname']) ? -1:(a['firstname'] > b['firstname']) ? 1:0

我们通过手动编写了一个函数实现了想要的功能。sortBy 可以这样使用

`// 根据 firstname 排序

people.sort(sortBy(‘firstname’))

// 返回

[

{ firstname: ‘aaFirstName’,lastName: ‘cclastName’},

{ firstname: ‘bbFirstName’,lastName: ‘bblastName’},

{ firstname: ‘ccFirstName’,lastName: ‘aalastName’},

]

// 根据 lastname 排序

people.sort(sortBy(‘lastname’))

// 返回

[

{ firstname: ‘ccFirstName’,lastName: ‘aalastName’},

{ firstname: ‘bbFirstName’,lastName: ‘bblastName’},

{ firstname: ‘aaFirstName’,lastName: ‘cclastName’},

]`

和以前一样!

分享

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

// 返回

[

{ firstname: ‘ccFirstName’,lastName: ‘aalastName’},

{ firstname: ‘bbFirstName’,lastName: ‘bblastName’},

{ firstname: ‘aaFirstName’,lastName: ‘cclastName’},

]`

和以前一样!

分享

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值