美文网首页
js回调相关知识点(发布订阅)

js回调相关知识点(发布订阅)

作者: 我叫Aliya但是被占用了 | 来源:发表于2019-06-11 01:05 被阅读0次

    Object.prototype.toString.call('str') => "[object String]"
    概念:装饰器、函数柯里化、偏函数、after方法、发布订阅、观察者

    装饰器

    Function.prototype.beforeCall = function () {
      console.info('方法守卫')
      this()
    }
    let fn = function () {
      console.info('方法内容')
    }
    fn.beforeCall()
    

    函数柯里化 & 偏函数

    把接受多个参数的函数,变换成接受一个单一参数的函数,并且返回接受余下的参数而且返回结果的新函数
    偏函数:入参变为多个

    // 改造bind
    var temp = {name: 'Lili'} 
    var obj = {
      name: 'fn',
      fn: function (a, b, c) {
        console.info('方法内容', this.name, a, b, c)
      }
    }
    Function.prototype.mybind = function (_t) {
      let self = this
      return function () { self.call(_t, ...arguments) }
    }
    obj.fn.mybind(temp)(1, 2, 3)
    

    after方法

    被触发指定次数后执行

    function after (times, fn) {
      let n = 1
      return function () {
        if (n == times) fn(...arguments)
        else n++
      }
    }
    let fn = function (a) {
      console.info('方法内容', a)
    }
    let newfn = after(3, fn)
    newfn(1)
    newfn(2)
    newfn(3)
    

    发布订阅

    let fakeBus = function () {
      this.eventList = {}
    }
    fakeBus.prototype.$on = function (order, fn) {
      this.eventList[order]
        ? this.eventList[order].push(fn)
        : this.eventList[order] = [fn]
    }
    fakeBus.prototype.$emit = function (order, ...args) {
      if (this.eventList[order]) {
        this.eventList[order].forEach(fn => {
          fn(...args)
        });
      }
    }
    let bus = new fakeBus()
    bus.$on('bit', msg => console.info(1, msg))
    bus.$on('bit', msg => console.info(2, msg))
    bus.$emit('bit', 'ouch')
    

    观察者

    发布与订阅间有关系

    class Watcher {
      constructor (obj) {
        this.__event_list = {}
        this.__watch(obj)
      }
    
      __watch (obj, father_key) {
        father_key = father_key || ''
        Object.keys(obj).forEach(item => {
          if (typeof obj[item] == 'object') {
            this.__watch(obj[item], father_key + item + '.')
          }
          else this.__append_getset(obj, item, father_key + item)
        })
      }
    
      __append_getset (obj, key, order) {
        let self = this
        let temp = obj[key]
        Object.defineProperty(obj, key, {
          get () { return temp },
          set (newval) { 
            self.__$emit(order, newval, temp)
            temp == newval; 
          }
        })
      }
    
      __$emit (order, newval, oldval) {
        if (this.__event_list[order]) {
          this.__event_list[order].forEach(fn => fn(newval, oldval))
        }
      }
    
      // $on
      $goWatch (order, fn) {
        this.__event_list[order]
            ? this.__event_list[order].push(fn)
            : this.__event_list[order] = [fn]
      }
    }
    let obj = {
      a: 1,
      b: {
        name: 'haha'
      }
    }
    let obj_wc = new Watcher(obj)
    obj_wc.$goWatch('a', function (newval, oldval) {
      console.info(`a的值从 ${oldval} 改变为 ${newval} `)
    })
    obj_wc.$goWatch('a', function (newval, oldval) {
      console.info(`a的值是 ${newval} ,但以前是 ${oldval}`)
    })
    obj_wc.$goWatch('b.name', function (newval, oldval) {
      console.info(`b.name的值是 ${newval} ,但以前是 ${oldval}`)
    })
    obj.a = 4
    obj.b.name = 'heihei'
    
    

    相关文章

      网友评论

          本文标题:js回调相关知识点(发布订阅)

          本文链接:https://www.haomeiwen.com/subject/ymztfctx.html