After reading the tomxuArticle, Close up one of his JSProgram.
Function concreteclass (){
This. Required mtask = function (){
Console. Log (this)
This. pretask ();
Console. Log ('some Code ');
This. posttask ();
}
}
Concreteclass. Prototype. Add = function () {console. Log ('for test use. ')}
Function abstractdecorator (decorated) {// abstract Abstract
This. Required mtask = function (){
Decorated. receivmtask ();
}
}
Function concretedecoratorclass (decorated ){
This. base = abstractdecorator;
This. Base (decorated );
Decorated. pretask = function (){
Console. Log ('pre-calling ...');
}
Decorated. posttask = function (){
Console. Log ('post-calling ...');
}
}
VaR C1 = new concreteclass ();
VaR d1 = new concretedecoratorclass (C1 );
D1.performtask ();
VaR C2 = new concreteclass ();
// Newly added. The code above is Uncle Tom's code
C2.pretask (); // typeerror: c2.pretask is not a function
VaR D2 = new concretedecoratorclass ();
D2.20.mtask (); // typeerror: decorated is undefined
The execution process of the above program is as follows:
1. After loading, register three functions concreteclass, abstractdecorator, and concretedecoratorclass, but do not execute internal methods.
2. var C1 = new concreteclass (); after the execution ends, jump to the concreteclass function to add attributes or methods, add the performtask method, but do not execute
3. var d1 = new concretedecoratorclass (C1); run until now:
A: Jump to the concreteclass function and add the base attribute. This. base = abstractdecorator;
This. base = function abstractdecorator (decorated) {// abstract Abstract
This. Required mtask = function (){
Decorated. receivmtask ();
}
}
Then, decorated. pretask and decorated. posttask are sequentially executed to add these two methods to the C1 object instance.
B: This. Base (decorated); Changes to abstractdecorator (C1), and runs immediately. Jump to the abstractdecorator (decorated) function,
This in it represents concretedecoratorclass [current scope], adds the performtask attribute, and
This. Required mtask = function (){
C1.performtask ();
}
That is, the object instance D1 has the javasmtask attribute instead of the concretedecoratorclass attribute of the concretedecoratorclass.
C: c2.pretask (); until now, search for the pretask () method in the object instance and execute
Search process: from the concreteclass constructor, when this. Base (decorated); is found:
This. Required mtask = function (){
C1.performtask ();
}
Therefore, this. implements mtask () to c1.performtask ();, so c2.pretask () is changed to c1.performtask (). So far, the internal C1'
This. pretask ();
Console. Log ('some Code ');
This. posttask ();
The preceding steps are completed.
VaR C2 = new concreteclass ();
C2.pretask (); // typeerror: c2.pretask is not a function
VaR D2 = new concretedecoratorclass ();
D2.20.mtask (); // typeerror: decorated is undefined
The two are used to view concreteclass and concretedecoratorclass