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'
网友评论