高阶函数(一)

上一章简单的创建了些函数并执行了函数,然后自己封装了一个forEach的API,我们给这个forEach传了一个特别的参数,他是一个函数。那么这个forEach其实就是一个高阶函数。

1.数据类型

js的数据类型目前看来就是八种:常见的Nmber,String,Boolean,null,undefined,Object,加上ES6新增的symbol,还有个ES11加的BigInt。其中Object我们称为引用数据类型或者复杂数据类型,他是一个大类,object,fuction,array,date...都属于Object

1.1传递函数:

自己写一个函数试试:判断参数的数据类型

const confirmType=(arg)=>{
     console.log(typeof arg);
}
const data=1
confirmType(data)

我们把它给稍微改一下后

const dataFn=()=>{
    console.log("这是函数");
}
const confirmType=(arg)=>{
    if(typeof arg==="function")
    arg()
    else
     console.log("不是函数,是"+ typeof arg);
}
confirmType(dataFn)
confirmType(1)
//这是函数
//不是函数,是number

1.2 返回函数

上面的例子我们是把一个函数传递给另一个函数,现在我们再写一个函数返回另一个函数。

let crazy=()=>String
console.log(crazy()("11111")); 

crazy返回了一个String函数,但是只返回没有执行。

我们上面铺垫这么多是为了引入高阶函数的定义:高阶函数是接收函数作为参数,或者返回函数作为输出的函数。

2.抽象和高阶函数

首先我们需要知道什么是抽象。我觉得下面这个文章说的挺好的:

在计算机领域,究竟何为“抽象”,它又为何重要? - 知乎

抽象让我们专注于预定的目标,而不必关心底层的系统概念。

2.1通过高阶函数实现抽象

比如我们之前封装的API forEach,就是函数抽象出了遍历数组的问题。当你使用它时,不需要理解它怎么遍历的。

我们再来写一个遍历对象的高阶函数:

const forEachObject=(obj,fn)=>{
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            fn(key,obj[key])
        }
    }
}
const obj={a:1,b:2}
forEachObject(obj,(k,v)=>console.log(k+":"+v))
//a:1
//b:2

 2.2控制流程处理

我们简单的创建一个unless函数,接收一个断言,如果是false就调用fn

查找偶数:

const forEach=(array,fn)=>{
    for(let i=0;i<array.length;i++){
        fn(array[i])
    }
}
const unless=(boo,fn)=>{
    if(!boo) fn()
}
forEach([1,2,3,4,5],(number)=>{
    unless((number%2),()=>{
        console.log(number);
    })
})
//2 4

3.实用的高阶函数

上面都是我们自己封装的高阶函数,现在我们来讨论一些真实的高阶函数:

3.1 every函数

他接受两个参数,一个数组和一个函数

const every=(arr,fn)=>{
    let result =true
    for(let i=0;i<arr.length;i++){
        result=result&&fn(arr[i])
    }
    return result
}
every([NaN,NaN,NaN],isNaN) //ture
every([NaN,NaN,4],isNaN) //false
//用 for ... of 循环重写every
const every1=(arr,fn)=>{
let result =true
for(const v of arr)
result=result&&fn(v)
return result
}

3.2 some函数

some函数和every函数基本一样,只是给定的result初始值有区别,some给定的是false,同时将&&换成||

3.3 sort函数

sort是Array原型的内置函数。

arr.sort([compareFn])这里的compareFn是可选的,如果我们不提供compareFn,元素将会被转化为字符串并按照Unicode编码点顺序排序。在编写compareFn之前我们先实现一下逻辑:

Array.prototype.sort() - JavaScript | MDN

function compareFn(a, b) {
  if (在某些排序规则中,a 小于 b) {
    return -1;
  }
  if (在这一排序规则下,a 大于 b) {
    return 1;
  }
  // a 一定等于 b
  return 0;
}

我们在看完Mdn上面的compareFn的算法后,我们自己尝试去用一个函数返回的值去入参。

const sortBy=(v)=>{
    return (a,b)=>{
        let result =(a[v]<b[a])?-1:(a[v]>b[v])?1:0
        return result
    }
}

sortBy接受一个参数v并返回一个函数接受两个参数。我们这时候就需要注意一下,这个返回的函数如何让得来?这里就用到了闭包,下一章我们将介绍闭包,闭包和高阶函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值