JavaScript Tutorial/Object Oriented/zInherit
Содержание
Using inheritFrom method from zInherit Library
<source lang="javascript">
<html> <head> <title>Example</title> <script type="text/javascript"> /*------------------------------------------------------------------------------
* JavaScript zInherit Library * Version 1.0 * by Nicholas C. Zakas, http://www.nczonline.net/ * Copyright (c) 2004-2005 Nicholas C. Zakas. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *------------------------------------------------------------------------------ */
/**
* Inherits properties and methods from the given class. * @scope public * @param fnClass The constructor function to inherit from. */
Object.prototype.inheritFrom = function (fnClass /*: Function */) /*:void*/ {
/** * Inherits all classes going up the inheritance chain recursively. * @param fnClass The class to inherit from. * @param arrClasses The array of classes to build up. * @scope private */ function inheritClasses(fnClass /*:Function*/, arrClasses /*:Array*/) /*:void*/ { arrClasses.push(fnClass); if (typeof fnClass.__superclasses__ == "object") { for (var i=0; i < fnClass.__superclasses__.length; i++){ inheritClasses(fnClass.__superclasses__[i], arrClasses); } } } if (typeof this.constructor.__superclasses__ == "undefined") { this.constructor.__superclasses__ = new Array(); } inheritClasses(fnClass, this.constructor.__superclasses__); for (prop in fnClass.prototype) { if (typeof fnClass.prototype[prop] == "function") { this[prop] = fnClass.prototype[prop]; } }
}; /**
* Determines if the given object is an instance of a given class.
* This method is necessary because using {@link #inheritFrom} renders
* the JavaScript instanceof
operator useless.
* @param fnClass The constructor function to test.
* @return True if the object is an instance of the class, false if not.
* @scope public
*/
Object.prototype.instanceOf = function (fnClass /*:Function*/) /*: boolean */ {
if (this.constructor == fnClass) { return true; } else if (typeof this.constructor.__superclasses__ == "object") { for (var i=0; i < this.constructor.__superclasses__.length; i++) { if (this.constructor.__superclasses__[i] == fnClass) { return true; } } return false; } else { return false; }
}; </script> </head> <body> <script type="text/javascript"> function ClassX() {
this.messageX = "This is the X message."; if (typeof ClassX._initialized == "undefined") { ClassX.prototype.sayMessageX = function () { alert(this.messageX); }; ClassX._initialized = true; }
} function ClassY() {
this.messageY = "This is the Y message."; if (typeof ClassY._initialized == "undefined") { ClassY.prototype.sayMessageY = function () { alert(this.messageY); }; ClassY._initialized = true; }
} function ClassZ() {
ClassX.apply(this); ClassY.apply(this); this.messageZ = "This is the Z message."; if (typeof ClassZ._initialized == "undefined") { ClassZ.prototype.inheritFrom(ClassX); ClassZ.prototype.inheritFrom(ClassY); ClassZ.prototype.sayMessageZ = function () { alert(this.messageZ); }; ClassZ._initialized = true; }
} var objZ = new ClassZ(); objZ.sayMessageX(); objZ.sayMessageY(); objZ.sayMessageZ(); </script>
</body> </html></source>
Using instanceOf method from zInherit Library
<source lang="javascript">
<html> <head> <title>Example</title> <script type="text/javascript"> /*------------------------------------------------------------------------------
* JavaScript zInherit Library * Version 1.0 * by Nicholas C. Zakas, http://www.nczonline.net/ * Copyright (c) 2004-2005 Nicholas C. Zakas. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *------------------------------------------------------------------------------ */
/**
* Inherits properties and methods from the given class. * @scope public * @param fnClass The constructor function to inherit from. */
Object.prototype.inheritFrom = function (fnClass /*: Function */) /*:void*/ {
/** * Inherits all classes going up the inheritance chain recursively. * @param fnClass The class to inherit from. * @param arrClasses The array of classes to build up. * @scope private */ function inheritClasses(fnClass /*:Function*/, arrClasses /*:Array*/) /*:void*/ { arrClasses.push(fnClass); if (typeof fnClass.__superclasses__ == "object") { for (var i=0; i < fnClass.__superclasses__.length; i++){ inheritClasses(fnClass.__superclasses__[i], arrClasses); } } } if (typeof this.constructor.__superclasses__ == "undefined") { this.constructor.__superclasses__ = new Array(); } inheritClasses(fnClass, this.constructor.__superclasses__); for (prop in fnClass.prototype) { if (typeof fnClass.prototype[prop] == "function") { this[prop] = fnClass.prototype[prop]; } }
}; /**
* Determines if the given object is an instance of a given class.
* This method is necessary because using {@link #inheritFrom} renders
* the JavaScript instanceof
operator useless.
* @param fnClass The constructor function to test.
* @return True if the object is an instance of the class, false if not.
* @scope public
*/
Object.prototype.instanceOf = function (fnClass /*:Function*/) /*: boolean */ {
if (this.constructor == fnClass) { return true; } else if (typeof this.constructor.__superclasses__ == "object") { for (var i=0; i < this.constructor.__superclasses__.length; i++) { if (this.constructor.__superclasses__[i] == fnClass) { return true; } } return false; } else { return false; }
}; </script> </head> <body> <script type="text/javascript"> function Shape(iSides) {
this.sides = iSides; if (typeof Shape._initialized == "undefined") { Shape.prototype.getArea = function () { return 0; }; Shape._initialized = true; }
} function Triangle(iBase, iHeight) {
Shape.call(this, 3); this.base = iBase; this.height = iHeight; if (typeof Triangle._initialized == "undefined") { Triangle.prototype.inheritFrom(Shape); Triangle.prototype.getArea = function () { return 0.5 * this.base * this.height; }; Triangle._initialized = true; }
} function Rectangle(iLength, iWidth) {
Shape.call(this, 4); this.length = iLength; this.width = iWidth; if (typeof Rectangle._initialized == "undefined") { Rectangle.prototype.inheritFrom(Shape); Rectangle.prototype.getArea = function () { return this.length * this.width; }; Rectangle._initialized = true; }
}
var triangle = new Triangle(12, 4); var rectangle = new Rectangle(22, 10); alert(triangle.sides); alert(triangle.getArea()); alert(rectangle.sides); alert(rectangle.getArea()); alert(triangle.instanceOf(Triangle)); alert(triangle.instanceOf(Shape)); alert(rectangle.instanceOf(Rectangle)); alert(rectangle.instanceOf(Shape)); </script>
</body> </html></source>
Using zInherit Library to build class inheritance
The zInherit library adds two methods to the Object class: inheritFrom() and instanceOf().
The following line uses prototype chaining to inherit methods from BaseClass to SubClass:
<source lang="javascript">
SubClass.prototype = new BaseClass();</source>
Using zInherit Library to build class inheritance in three levels
<source lang="javascript">
<html> <head> <title>Example</title> <script type="text/javascript"> /*------------------------------------------------------------------------------
* JavaScript zInherit Library * Version 1.0 * by Nicholas C. Zakas, http://www.nczonline.net/ * Copyright (c) 2004-2005 Nicholas C. Zakas. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *------------------------------------------------------------------------------ */
/**
* Inherits properties and methods from the given class. * @scope public * @param fnClass The constructor function to inherit from. */
Object.prototype.inheritFrom = function (fnClass /*: Function */) /*:void*/ {
/** * Inherits all classes going up the inheritance chain recursively. * @param fnClass The class to inherit from. * @param arrClasses The array of classes to build up. * @scope private */ function inheritClasses(fnClass /*:Function*/, arrClasses /*:Array*/) /*:void*/ { arrClasses.push(fnClass); if (typeof fnClass.__superclasses__ == "object") { for (var i=0; i < fnClass.__superclasses__.length; i++){ inheritClasses(fnClass.__superclasses__[i], arrClasses); } } } if (typeof this.constructor.__superclasses__ == "undefined") { this.constructor.__superclasses__ = new Array(); } inheritClasses(fnClass, this.constructor.__superclasses__); for (prop in fnClass.prototype) { if (typeof fnClass.prototype[prop] == "function") { this[prop] = fnClass.prototype[prop]; } }
}; /**
* Determines if the given object is an instance of a given class.
* This method is necessary because using {@link #inheritFrom} renders
* the JavaScript instanceof
operator useless.
* @param fnClass The constructor function to test.
* @return True if the object is an instance of the class, false if not.
* @scope public
*/
Object.prototype.instanceOf = function (fnClass /*:Function*/) /*: boolean */ {
if (this.constructor == fnClass) { return true; } else if (typeof this.constructor.__superclasses__ == "object") { for (var i=0; i < this.constructor.__superclasses__.length; i++) { if (this.constructor.__superclasses__[i] == fnClass) { return true; } } return false; } else { return false; }
}; </script> </head> <body> <script type="text/javascript">
function Shape(iSides) {
this.sides = iSides;
} Shape.prototype.getArea = function () {
return 0;
}; function Triangle(iBase, iHeight) {
Shape.call(this, 3); this.base = iBase; this.height = iHeight;
} Triangle.prototype.inheritFrom(Shape); Triangle.prototype.getArea = function () {
return 0.5 * this.base * this.height;
}; function Rectangle(iLength, iWidth) {
Shape.call(this, 4); this.length = iLength; this.width = iWidth;
} Rectangle.prototype.inheritFrom(Shape); Rectangle.prototype.getArea = function () {
return this.length * this.width;
}; var triangle = new Triangle(12, 4); var rectangle = new Rectangle(22, 10); alert(triangle.sides); alert(triangle.getArea()); alert(rectangle.sides); alert(rectangle.getArea()); alert(triangle.instanceOf(Triangle)); alert(triangle.instanceOf(Shape)); alert(rectangle.instanceOf(Rectangle)); alert(rectangle.instanceOf(Shape)); </script>
</body> </html></source>