Mega Code Archive

 
Categories / JavaScript Tutorial / Object Oriented
 

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: SubClass.prototype = new BaseClass(); This line can be replaced with the following: SubClass.prototype.inheritFrom(BaseClass); The inheritFrom() method accepts the class from which to copy the methods. The inheritFrom() method doesn't actually create a new instance of the class to inherit from. The inheritFrom() method call must be used exactly where the prototype assignment normally occurs. The instanceOf() method is a replacement for the instanceof operator. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html>     <head>         <title>Page title</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 <code>instanceof</code> 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>         <script type="text/javascript">                     //sample class            function Friend(sName) {                this.name = sName;                           }                        Friend.prototype.supports = function () {                alert("Supporting you...");            };                        //sample class            function Animal(sType) {                this.type = sType;            }                        Animal.prototype.loves = function () {                alert("Loving you...");            };                        //sample class inheriting from both Friend and Animal            function Dog(sName) {                            //inherit properties from Friend                Friend.call(this, sName);                                //inherit properties from Animal                Animal.call(this, "dog");                        }                        //inherit methods from Friend            Dog.prototype.inheritFrom(Friend);                        //inherit methods from Animal            Dog.prototype.inheritFrom(Animal);                               </script>       </head>     <body>                  <script type="text/javascript">                      var oDog = new Dog("Sparky");                          //try method from Friend             oDog.supports();                          //try method from Animal             oDog.loves();                          //is this an instance of Friend?             alert("Is instance of Friend: " + oDog.instanceOf(Friend));                          //is this an instance of Animal?             alert("Is instance of Animal: " + oDog.instanceOf(Animal));                          //is this an instance of Dog?             alert("Is instance of Dog: " + oDog.instanceOf(Dog));                              </script>         <P>This example defines a <code>Friend</code> class and an <code>Animal</code>         class. Then, it defines a <code>Dog</code> class that inherits from both.</p>     </body> </html>