定义
在不改变原对象的基础上,通过对其进行包装扩展(添加属性和方法)使原有对象可以满足用户更复杂的需求
demo
缓存函数引用
let decorator = function (input,type) {let inp = document.getElementById(input);let click;if(Object.prototype.toString.call(inp.onclick) === '[object Function]'){// 缓存原有事件click = inp.onclick;}inp.onclick = function () {// 事件原有函数click && click();fn();}};
缺点
要维护额外的中间变量(_foo),如果装饰链过长,中间变量就会越来越多
可能会存在this被劫持问题
var getId = document.getElementById;document.getElementById = function(ID){console.log(1);return getId(ID);}document.getElementById('demo');
修改:
var getId = document.getElementById;document.getElementById = function(ID){console.log(1);return getId.call(document, ID);}document.getElementById('demo');
AOP装饰函数
前置装饰
Function.prototype.before = function(beforeFunc){var that = this;return function(){beforeFunc.apply(this, arguments);return that.apply(this, arguments);}}
后置装饰
Function.prototype.after = function(afterFunc){var that = this;return function(){var ret = that.apply(this, arguments);afterFunc.apply(this, arguments);return ret;}}
总结
1、装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被装饰者)的场合,都可以用装饰过得对象代替原始对象。
2、可以用一个或多个装饰者包装一个对象(被装饰者)
3、装饰者可以在所委托的装饰者行为之前或之后加上自己的行为,以达到特定的目的
4、被装饰者可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
5、装饰者会导致出现很多小对象,如果过度使用,会让程序变得复杂。
