Copy Code code as follows:
Copy Code code as follows:
function A ()
{
THIS.V1 = 10;
}
A.prototype.print = function ()
{
alert (THIS.V1);
}
function B ()
{
}
B.prototype = new A ();
New B (). print ();
Running this code output is 10, it looks as if Class B inherits the method print of Class A, and produces the correct output, the actual execution process is in the object generated by Class B, you cannot get method print directly, so find the corresponding method in its prototype attribute. The starting point for this scenario is very good, as in Class B, where Class B is invoked, otherwise the method of the same name in its prototype property (Class A) is invoked. Sometimes, however, we need subclasses to invoke methods that have the same name as the parent class, such as Class B instead
Copy Code code as follows:
function B ()
{
This.v2 = 15;
}
B.prototype = new A ();
B.prototype.print = function ()
{
This.prototype.print.call (this);
alert (THIS.V2);
}
New B (). print ();
In which, This.prototype.print is the corresponding print method of Class A, the output is 10 and 15, seems to solve the problem, in fact, we will inherit a layer
Copy Code code as follows:
function C ()
{
This.v3 = 20;
}
C.prototype = new B ();
C.prototype.print = function ()
{
This.prototype.print.call (this);
alert (THIS.V3);
}
New C (). print ();
The output we're expecting is 10, 15, 20, but unfortunately, the result is that the system goes into a dead loop.
Because when this method is executed,
Copy Code code as follows:
C.prototype.print = function ()
{
This.prototype.print.call (this);
alert (THIS.V3);
}
The following methods will be called circularly until the stack overflows
Copy Code code as follows:
B.prototype.print = function ()
{
This.prototype.print.call (this);
alert (THIS.V2);
}
The right wording should now be changed to
Copy Code code as follows:
B.prototype.print = function ()
{
A.prototype.print.call (this);
alert (THIS.V3);
}
C.prototype.print = function ()
{
B.prototype.print.call (this);
alert (THIS.V3);
}
But in the event of a change in the inheritance relationship, it is not the best way to change a considerable number of references to the parent class, and in practice you might consider using _super instead of the name of the parent class, _this instead of the name, and then replace them with a standard method (super). Prototype or [This].prototype, which calls the specified method without ambiguity, is the real solution to JavaScript's OOP, and the relevant code is as follows:
Copy Code code as follows:
/*
When using an OOP inheritance system, you first define the class, finally execute the Extendsof initialization class, and use _super to refer to the parent class, for example, by using the _this reference itself,
For example:
function Extend2 ()
{
_super ();
}
Extend2.prototype.setValue = function (value)
{
_super.setvalue (value);
Alert ("Extend2:" + value);
}
Extend2.extendsof (EXTEND1);
class inherits the root of the tree as object. Note: All member functions that use escape must be defined before the Extendsof method call.
Object can set an autorun initialization code that begins with an underscore with the same name as the object name, as
Object._object = function () {...}
If the initialization code for the object does not exist, the initialization code for the parent object is automatically searched until all the search is complete
Copy Code code as follows:
Function.frblock =/* ("([^" ^\\]|\\ ") *" | " ([^'^\\]|\\')*'|\/([^\/^\\]|\\.) *\/) */;
Function.frspace =/\s+/g;
Function.frsign =/? (^|;|:| <|>|\?|,|\.| \/|\{|\}|\[|\]|\-|\+|\=|\(|\)|\*|\^|\%|\|) ?/g;
Function.frrefer =/_ (super|this) (\.[ ^(]+)?\(([^\)]*)\)/;
Function.prototype.FCompile = function (name)
{
Check whether it is a constructor of a class or a property of a class, and a null representation of the name argument is a constructor
if (name)
{
The property of a class is not a function implementation, which is directly assigned to a subclass and then exits
if (typeof This.prototype[name]!= "function")
{
Window[this. Fclassname].prototype[name] = This.prototype[name];
Return
}
var s = this.prototype[name].tostring ();
}
Else
{
var s = this.tostring ();
}
var B = "";
var R;
Filter whitespace characters
while (R = Function.FRBlock.exec (s))
{
s = regexp.rightcontext;
B + + RegExp.leftContext.replace (function.frspace, ""). Replace (Function.frsign, "$") + r[1];
}
B + + s.replace (function.frspace, ""). Replace (Function.frsign, "$");
var i = B.indexof ("(");
var j = b.indexof (")", I);
if (!name)
{
This. Fclassname = b.substring (9, I);
}
var cn = this. Fclassname;
var arg = b.substring (i + 1, j);
s = b.substring (j + 2, b.length-1);
b = "";
Make call escape and replace _super,_this with the specified method
for (var n = 0; r = Function.FRRefer.exec (s); n++)
{
if (r[2])
{
if (!name &&!n)
{
b = this. Fsuperclass.fclassname + ". Apply (this,arguments);";
}
R[2] = ". Prototype" + r[2];
}
else if (r[1] = = "This")
{
The JS function does not differentiate between parameters, and constructors do not allow recursion to call itself
Throw "constructor Call Mustn" _this (); \ "in a constructor";
}
else if (name | | Regexp.leftcontext)
{
Throw "constructor call must to be the ' the ' the ' statement in a constructor ';
}
Else
{
R[2] = "";
}
s = regexp.rightcontext;
B + + Regexp.leftcontext + (r[1] = = "This"? Cn:this. Fsuperclass.fclassname) + r[2] + (r[3]? ". Call (This," + r[3] + ")": ". Apply (This,arguments)");
}
if (n)
{
b = = s;
}
else if (name)
{
No calls for _this,_super, no compilation
Window[cn].prototype[name] = This.prototype[name];
Return
}
Else
{
is automatically added when there is no call to the parent class constructor
b = this. Fsuperclass.fclassname + ". Apply (This,arguments);" + S;
}
Compilation result Assignment
if (name)
{
Eval (CN + ". prototype." + name + "=function (" + arg + ") {" + B + "}");
}
Else
{
Eval (cn + "=function" + arg +) {"+ B +"; if (this.constructor== "+ CN +") "+ CN +". _ "+ CN +". Apply (this,arguments);} ");
WINDOW[CN]. Fclassname = CN;
}
}
Function.prototype.extendsOf = function (superclass)
{
This. Fsuperclass = superclass;
Compiling all the functions of a class
This. Fcompile ();
for (var name in This.prototype)
{
This. Fcompile (name);
}
var clazz = Window[this. Fclassname];
Clazz. Fsuperclass = superclass;
Copy parent class The Neutron class does not implement functions and properties
var prototype = Clazz.prototype;
for (var name in Superclass.prototype)
{
if (!prototype[name])
{
Prototype[name] = Superclass.prototype[name];
}
}
Replication initialization method, in the form of Object._object
for (var c = this;; c = c.fsuperclass)
{
if (c["_" + C.fclassname])
{
Clazz["_" + clazz. Fclassname] = c["_" + c.fclassname];
Return
}
}
}
/*
Built-in object class provides support for OOP
*/
Object.fclassname = "Object";
Object._object = function.instance;
Object.prototype.instanceOf = function (clazz)
{
for (var C = this.constructor C; c = c.fsuperclass)
{
if (c = = Clazz)
{
return true;
}
}
return false;
}