Sometimes we don't want a class that is inherently huge and contains many responsibilities at once. Then we can use the decorated pattern.
Decorative patterns can dynamically add additional responsibilities to an object without affecting other objects derived from the class.
Decorative pattern inserts an object into another object, actually equivalent to the object being wrapped by another object, forming a chain of packaging.
Without altering the original function, add some extra functionality to the 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) must maintain the intermediate variable
(2) may encounter this hijacked problem
There is no such annoyance in the window.onload example, because when calling a normal function _onload, this also points to window, just as it was when Window.onload was invoked.
2. This is hijacked:
var _getelementbyid = document.getElementById;
document.getElementById = function (id) {
console.log (1);
return _getelementbyid (ID);
}
return _getelementbyid (ID); Error "Uncaught typeerror:illegal invocation"
Because _getelementbyid is a global function, when the global function is invoked, this points to window, and in document.getElementById this is expected to point to document.
3. Resolve this to be hijacked:
var _getelementbyid = document.getElementById;
document.getElementById = function (id) {
console.log (1);
return _getelementbyid.call (document, id);
}
Second, the use of AOP decorative functions
/* Let the newly added function execute before the original function (front decoration)/
Function.prototype.before = function (beforefn) {
var _self = this;
return function () {
beforefn.apply (this, arguments); The parameters that are received by the new function are returned to
_self.apply (this, arguments);
/* Let the newly added function execute after the original function (after decoration)/
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);
});
Third, avoid the pollution of the prototype
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);
});
Iv. Example – Plug-in form validation
Combined with the "form validation" in the " Learning JavaScript design pattern" strategy , the application of Ajax to submit data validation is great!
Modify the above before method
var before = function (FN, beforefn) {return
function () {
if (beforefn.apply (this, arguments) = = False) {
//b Eforefn returns false, direct return, do not perform the back of the original function returned
;
Return fn.apply (this, arguments);
};
/* Analog data validation/
var validate = function () {
if (username = = "") {
console.log validation failed! ");
return false;
}
return true;
}
/* Simulate AJAX submission/
var formsubmit = function () {
console.log ("Submit!!! ");
}
Username = 1;
Formsubmit = before (formsubmit, validate); Submit!!!
formsubmit ();
Username = "";
Formsubmit = before (formsubmit, validate); Validation failed!
Formsubmit ();
Five, decorator mode and agent mode
Same point: Both patterns describe how to provide an indirect reference to an object, and their implementation part retains a reference to another object and sends a request to that object.
Difference:
(1) Agent mode: When direct access to local inconvenient or not meet the requirements, for this ontology to provide a replacement. Define key features locally, while agents provide or deny access to it, or go some extra things before accessing the ontology. (It does the same thing as the body)
(2) Decorator mode: Dynamically adding behavior to the object. (initially unsure of the full functionality of the object, adding new responsibilities and behavior to the object)
I hope this article will help you learn about JavaScript programming.