理解JavaScript中的高阶函数

吐槽君 分类:javascript

首先我们来看一下维基百科对于高阶函数的定义:

在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:

  • 接受一个或多个函数作为输入
  • 输出一个函数

简单点来说,我们定义一个函数时,参数是函数或者返回值是函数,这个函数高阶函数。而对于JavaScript来说这两种情况都满足。

函数作为参数

    function callbackFn() {
        console.log('高阶函数')
    }
    function fnParam(fn) {
        console.log('普通函数')
        // fn 函数作为参数传递
        fn()
    }
    // 测试
    fnParam(callbackFn)
    
 

上述例子fn函数作为参数传递,这种函数被称作为回调函数

回调函数是异步的基石,上述例子中 callbackFn 作为参数传递到 fnParam 函数中,callbackFn 的执行
权由fnParam 决定。

在JavaScript语言中内置的很多这种函数作为参数的高阶函数,例如

  • Array.prototype.map
  • Array.prototype.filter
  • Array.prototype.find
  • ....

以 Array.prototype.map 为例子进行详细讲解

使用高阶函数

      // map 使用实例
     const arr = [1, 2, 3, 4]
     const result = arr.map(item => item * 2)
     console.log(arr)  // [1, 2, 3, 4]
     console.log(result)  // // [2, 4, 6, 8]
 

不使用高阶函数

     // 同步代码实现 map 功能
     const arr = [1, 2, 3, 4]
     const result = []
     for(let i = 0; i < arr.length; i++) {
         const item = arr[i]
         result.push(item * 2)
     }
     console.log(arr)  // [1, 2, 3, 4]
     console.log(result)  // // [2, 4, 6, 8]
 

模拟实现

    // 模拟 map
    const map = (arr,fn)=>{
        let res = [];
        for(let i = 0; i < arr.length; i++){
            res.push(fn(i))
        }
        return res;
    }
    // 测试
    const newAry = map([1,23,4,5,6],item=>item**2)
    console.log(newAry) // [1, 529, 16, 25, 36]
 
    // 模拟 filter
    function filter(arr,fn){
        let res = [];
        for(let i = 0; i < arr.length; i++){
            if(fn(arr[i])){
                res.push(arr[i])
            }
        }
        return res
    }
    // 测试
    const ary = filter([1,2,34,5,6],function(item){
        return item%2 === 0;
    })
    console.log(ary) // [2, 34, 6]
 

函数作为返回值

我们来看一个简单例子

    function getMsg() {
        const msg = 'hello msg'
        // 函数作为返回值
        return function() {
            console.log('msg')
        }
    }
    // 测试
    const firstAction = getMsg()
    firstAction() // hello msg
 

getMsg执行之后得到的是一个函数,这个函数赋值给了firstAction,这个firstAction就是函数作为返回值。这里会产生闭包

接下来我们利用高阶函数这两个特性来实现一个只能调用一次的函数

    function once(fn) {
        let done = false
        return function() {
            if(!done) {
                done = true
                return fn.apply(this, arguments)
            }
        }
    }
    const pay = once(function(money) {
        console.log('支付了'+ money)
    })
    pay(5)
    pay(5)
    pay(5)
 

回复

我来回复
  • 暂无回复内容