The decorated pattern can dynamically add some additional responsibilities to an object without affecting other objects derived from this class.
The decorated pattern embeds one object into another object, which is actually equivalent to this object being wrapped by another object, forming a packaging chain.
Add some additional functions to the function without changing the original function
1. Save the original reference
window.onload = function() { console.log(1); }; var _onload = window.onload || function() {}; window.onload = function() { _onload(); console.log(2); }
Problem:
(1) Intermediate variables must be maintained
(2) This may be hijacked
In the example of window.onload, there is no such trouble because when calling the ordinary function _onload, this also points to window, just like when calling window.onload.
2. this is hijacked:
var _getElementById = document.getElementById; document.getElementById = function(id) { console.log(1); return _getElementById(id); } return _getElementById(id); // 报错“Uncaught TypeError: Illegal invocation”
Because _getElementById is a global function, when calling the global function, this points to the window, and in document.getElementById this is expected to point to the document.
3. Solve this being hijacked:
##
var _getElementById = document.getElementById; document.getElementById = function(id) { console.log(1); return _getElementById.call(document, id); }
Decorate the function with AOP
/* 让新添加的函数在原函数之前执行(前置装饰)*/ Function.prototype.before = function(beforefn) { var _self = this; return function() { beforefn.apply(this, arguments); // 新函数接收的参数会被原封不动的传入原函数 return _self.apply(this, arguments); }; };
/* 让新添加的函数在原函数之后执行(后置装饰)*/ Function.prototype.after = function(afterfn) { var _self = this; return function() { var ret = _self.apply(this, arguments); afterfn.apply(this, arguments); return ret; }; };
document.getElementById = document.getElementById.before(function() { console.log(1); });
Avoid polluting prototypes
var before = function(fn, beforefn) { return function() { beforefn.apply(this, arguments); return fn.apply(this, arguments); }; }; var after = function(fn, afterfn) { return function() { var ret = fn.apply(this, arguments); afterfn.apply(this, arguments); return ret; }; }; document.getElementById = before(document.getElementById, function(){ console.log(1); });
Decorator pattern and proxy pattern
Difference:
(1) Proxy mode: When direct local access is inconvenient or does not meet the needs, provide a substitute for this ontology. Define key functionality locally, and the agent provides or denies access to it, or does some extra things before accessing the ontology. (It still does the same thing as the ontology)
(2) Decorator mode: Dynamically add behaviors to the object. (You cannot determine all the functions of the object at the beginning, and actually add new responsibilities and behaviors to the object)
The above is the detailed content of Detailed examples of the difference between the function of JavaScript decorator pattern and proxy pattern. For more information, please follow other related articles on the PHP Chinese website!