# 1. 什么是高阶函数(before)

  • 如果一个函数的参数是一个函数(回调函数是一种高阶函数)
  • 如果一个函数返回一个函数,当前这个函数也是一个高阶函数

要求:在say函数的基础上,扩展一段自己的业务逻辑
解决办法:在函数的原型上,添加一个方法,在它之前调用

function say(a, b) {
  console. log('say', a, b); 
}

Function. prototype. before = function (callback) {
  return (... args) => {

    callback(); // before 里传递的回调函数
    this(...args);  // say 函数

  }
}

// 在 before 函数里定义 自己的业务逻辑代码
let beforeSay = say. before(function () {
  console. log('before say')
})

beforeSay('hello', 'world'); 

# 2. 高阶函数的应用 —— 柯里化

例题:封装一个判断变量类型的函数

function isType(type, value) {
  return Object. prototype. toString. call(value) === **[object ${type}]**; 
}

细分isType

function isType(type) {
  return function(value) {

    return Object.prototype.toString.call(value) === **[object ${type}]**;

  }
}

let isArray = isType('Array'); 
console. log(isArray([]))

# 3. 封装一个通用的currying函数

判断变量的类型

const currying = (fn, arr = []) => {
  let len = fn. length; // 获取函数参数的个数
  return function (... args) {

    arr = [...arr, ...args];
    if (arr.length < len) {
      return currying(fn, arr); // 递归不停地产生函数
    } else {
      return fn(...arr)
    }

  }
}

let isArray = currying(isType)('Array'); 
let isString = currying(isType)('String'); 
console. log(isArray([]))
console. log(isString([]))

currying求和

function sum(a, b, c, d, e, f) {
  return a + b + c + d + e + f; 
}

const currying = (fn, arr = []) => {
  let len = fn. length; // 获取函数参数的个数
  return function (... args) {

    arr = [...arr, ...args];
    if (arr.length < len) {
      return currying(fn, arr); // 递归不停地产生函数
    } else {
      return fn(...arr)
    }

  }
}

let res = currying(sum)(1, 2)(3, 4)(5)(6)  // 21

# 4. 回调函数处理异步并发请求问题

要求:读取完两个文本的内容后,打印该内容组成的文本对象school

let fs = require('fs'); 
let school = {}; 

function after (times, callback) {
  return function () {  // 闭包

    if(--times == 0) {
      callback()
    }

  }
}

// 定义 after高阶函数
// cb 函数执行两次之后,输出school
let cb = after(2, function () {
  console. log(school)
})

fs. readFile('. /name. txt', 'utf8', function (err, data) {

    school.name = data;
    cb();

}); 

fs. readFile('. /age. txt', 'utf8', function (err, data) {

    school.age = data;
    cb();

}); 

闭包

每次调cb函数的时候,在cb函数的执行上下文中都能读取到全局作用域下的times,使其不被销毁