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

2019-06-11  本文已影响0人  我叫Aliya但是被占用了

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'

上一篇下一篇

猜你喜欢

热点阅读