2024年最新函数式编程之高阶函数,888道Web前端高级面试题

最后

编程基础的初级开发者,计算机科学专业的学生,以及平时没怎么利用过数据结构与算法的开发人员希望复习这些概念为下次技术面试做准备。或者想学习一些计算机科学的基本概念,以优化代码,提高编程技能。这份笔记都是可以作为参考的。

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

名不虚传!字节技术官甩出的"保姆级"数据结构与算法笔记太香了

`// es6-functional.js

const times = (times,fn) => {

for(let i = 0; i < times; i++)

fn(i)

}`

times 与 forEach 函数类似,不同的是我们操作的是一个 number 而不是 array,如果要输出 0 - 99 中的偶数,就可以这么用

`times(100,function(n){

unless(n % 2,function(){

console.log(n + " 是偶数")

})

})`

我们将上面的代码抽象出循环,条件判断被放在一个简明的高阶函数中。

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’))

// 返回

基础面试题

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

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

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

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

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

`// 根据 firstname 排序

people.sort(sortBy(‘firstname’))

// 返回

基础面试题

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

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

[外链图片转存中…(img-Plu0atB5-1715742641790)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值