高阶函数和运用

157 阅读2分钟

高阶函数定义:

  1. 函数的参数是一个函数
  2. 一个函数返回一个函数 当前这个函数也是高阶函数
    function say() {
     return function(){
     
     }
    }
  • 高阶函数能解决很多问题,框架和库都有运用
  • eg1 : before方法 给某个方法,添加一个方法在它之前调用
function say(a,b){
    console.log('say',a,b)
}

Function.prototype.before = function (callback){
        return (...args) => {
            callback(); // 调用函数之前调用callback 可以包装自己的逻辑
            this(...args); // 指向say方法
        }
}

let beforeSay = say.before(function(){
    console.log('before say')
})
beforeSay('hello','world');

函数柯里化与反柯里化

  • 运用场景: 判断变量类型
  • typeof : 不能判断变量类型
  • constructor : 可以找到变量是怎么构造出来的
  • instanceof : 判断是谁的实例
  • Object.prototype.toString.call() : 对象原型上提供的方法

function isType2(Type){
  return function(value){
    return Object.prototype.toString.call(value) === `[Object ${type}]`
  }
}

let isArray = isType2('Array');
// 调用 isArray([])
// 通用curring

const curring = (fn,arr = []) => {
    let len = fn.length;
    return function(...args){
        let newArgs = [...arr, ...args];
        if(newArgs.length == len){
            fn(...newArgs);
        }else{
            return curring(fn, newArgs)
        }
    }
}

闭包: 函数的定义作用域和函数执行的作用域,不在同一个作用域;

常用设计模式:发布订阅模式和观察者模式

  • 发布订阅主要分为两个部分:on emit
  • on: 把一些函数维护到一个数组中;
  • emit: 让数组中的方法依次执行;(取出数组中函数来去执行)
  • on和emit之间没有之间管理,没有耦合在一起
let event = {
    arr: [], // 事件库
    on(){
        this.arr.push(fn);
    },
    emit(){ 
        this.arr.forEach(fn => fn())
    }
}

event.on(function(){
    if(Object.keys(school).length == 2){
       console.log('读取完毕')
    })
  
})

let school = {}
// 多个异步执行完毕之后读取school
fs.readFile('a.txt','utf8',(err, data) => {
    school.name = data;
    event.emit()
})
fs.readFile('b.txt','utf8',(err, data) => {
    school.name = data;
    event.emit()
})


  • 观察者模式: 发布和订阅直接有直接关联
  • 有观察者和被观察者 观察者需要放到被观察者中,被观察者状态反生变化通知观察者
// 观察者模式  
// 被观察者
class Subject{
    constructor(name){
        this.name = name;
        this.state = 'happy';
        this.observers = [] // 观察者对象
    }
    attach(observer){
        this.observers.push(observer)
    }
    setState(state){
        this.state = state;
        this.observers.forEach(observer => observer.update(this))
    }
}
class Observer{
    constructor(name){
        this.name = name;
    }
    update(baby){
        console.log()
    }
    
}
let baby = new Subject('小宝宝')
let parent = new Observer('家长')
// 小宝宝订阅观察者
baby.attach(parent)
baby.setState('被打了')
。。