装饰器模式: 动态地给函数赋能。
生活中的例子: 天气冷了, 就添加衣服来保暖;天气热了, 就将外套脱下;这个例子很形象地含盖了装饰器的神韵, 随着天气的冷暖变化, 衣服可以动态的穿上脱下。
let wear = function() {console.log('穿上第一件衣服')}const _wear1 = wearwear = function() {_wear1()console.log('穿上第二件衣服')}const _wear2 = wearwear = function() {_wear2()console.log('穿上第三件衣服')}wear()// 穿上第一件衣服// 穿上第二件衣服// 穿上第三件衣服
这种方式有以下缺点: 1: 临时变量会变得越来越多;2: this 指向有时会出错
// 前置代码Function.prototype.before = function(fn) {const self = thisreturn function() {fn.apply(new(self), arguments) // https://github.com/MuYunyun/blog/pull/30#event-1817065820return self.apply(new(self), arguments)}}// 后置代码Function.prototype.after = function(fn) {const self = thisreturn function() {self.apply(new(self), arguments)return fn.apply(new(self), arguments)}}
用后置代码来实验下上面穿衣服的 demo,
const wear1 = function() {console.log('穿上第一件衣服')}const wear2 = function() {console.log('穿上第二件衣服')}const wear3 = function() {console.log('穿上第三件衣服')}const wear = wear1.after(wear2).after(wear3)wear()// 穿上第一件衣服// 穿上第二件衣服// 穿上第三件衣服
但这样子有时会污染原生函数, 可以做点通变
const after = function(fn, afterFn) {return function() {fn.apply(this, arguments)afterFn.apply(this, arguments)}}const wear = after(after(wear1, wear2), wear3)wear()