Object.prototype.toString.call('str') => "[object String]"
概念:裝飾器、函數(shù)柯里化、偏函數(shù)、after方法、發(fā)布訂閱、觀察者
裝飾器
Function.prototype.beforeCall = function () {
console.info('方法守衛(wèi)')
this()
}
let fn = function () {
console.info('方法內(nèi)容')
}
fn.beforeCall()
函數(shù)柯里化 & 偏函數(shù)
把接受多個參數(shù)的函數(shù),變換成接受一個單一參數(shù)的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)
偏函數(shù):入?yún)⒆優(yōu)槎鄠€
// 改造bind
var temp = {name: 'Lili'}
var obj = {
name: 'fn',
fn: function (a, b, c) {
console.info('方法內(nèi)容', 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方法
被觸發(fā)指定次數(shù)后執(zhí)行
function after (times, fn) {
let n = 1
return function () {
if (n == times) fn(...arguments)
else n++
}
}
let fn = function (a) {
console.info('方法內(nèi)容', a)
}
let newfn = after(3, fn)
newfn(1)
newfn(2)
newfn(3)
發(fā)布訂閱
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')
觀察者
發(fā)布與訂閱間有關(guān)系
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} 改變?yōu)?${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'