Javascript Inheritance

Searching Google for “Javascript Inheritance” returns some interesting but, IMO, also frustrating results such as Douglas Crockford’s various takes in Classical Inheritance in JavaScript or Kevin Lindsey’s approach, the former not really providing a clear answer while the latter relies on the convention of attaching a “superclass” property to your objects and effectively requires glueing your objects together for each instance you create.

Meanwhile libraries like prototype and MochKit have evolved their own conventions and strategies which you may or not may not appreciate. I’m grumpy in each case . prototype, despite having some very cool code in it, extends built-in Javascript types like Object which I don’t appreciate – makes me nervous about mixing in other Javascript libraries from other sources. Meanwhile looking at MochKit (which may be the best AJAX implementation out there, having made good reference to twisted) suffers from the kind of smartness summarized here, when it comes to it’s “Base”.

An Alternative

There is another way which probably gives you most of what you expect if you’re coming from a language like Java (ooops – can’t seem to stop it ;)). This is thanks to Troels Knak-Nielsen (author of indite – the realtime validating wysiwyg widget) who told me about it a long time ago on the JPSpan mailing list here.


function copyPrototype(descendant, parent) {
    var sConstructor = parent.toString();
    var aMatch = sConstructor.match( /s*function (.*)(/ );
    if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
    for (var m in parent.prototype) {
        descendant.prototype[m] = parent.prototype[m];
    }
};

Note: above code updated after initial post re this comment

At first glance, with that regex, it looks like a hack but if you allow it to sink in (which has taken me more than a year), you realise that it isn’t. It’s worth bearing in mind what Troels had to say about it;

First off – I fully understand and agree to the point of not extending language functionality. That said I think the point in relation to javascript and inheritance is often misunderstood. It is central to javascript that it is a “typeless objectoriented language”. This goes for ECMAscript3.0 all the same. Where people most often get it wrong is when they mistake prototypes for classes – they are not.

In a typed OO-language the objects code lies with the class – objects are just instances. In js, the code lies in the object. Therefore, the object is not tied to the prototype. It is ok in js to manipulate the prototype runtime, even after objects has been instantiated. Consider doing that with a typed language.

Anyway. I have been working a lot with js recently, and found that one-level inheritance is simple enough using prototypes, but further inheritance cause trouble. I guess you came to the same conclusion with JPSpan. My first googling on the subject turned up a lot of wierd hacks, that I don’t appreciate. I eventually invented a solution witch I use, and witch I’m very happy with. It may look as a hack, but it works so well, that I kind of forgive it for that.

To defend myself further I’ll point out that it’s not a language extension, if you just understand what it does. It’s merely a utility that extends a prototype – Which should not be confused with class inheritance (though the result is the same).

It’s easiest to see Troels point by trying it…

Basic Inheritance

The way you’d expect…


function Animal() {
    this.species = "animal";
};

Animal.prototype.category = function() {
    alert(this.species);
};

function Dog() {
    // Call the parent constructor to setup
    // the parent object properties...
    this.Animal();
};

// Dog "inherits" from Animal
copyPrototype(Dog, Animal);

var d = new Dog();
d.category();

…and I get the alert “animal”

Another spin on that, this time without calling the parent constructor…


function Animal() {
    this.species = "animal";
};

Animal.prototype.category = function() {
    alert(this.species);
};

function Dog() {
    // No call to parent constructor
    this.species = "canine";
};

// Dog "inherits" from Animal
copyPrototype(Dog, Animal);

var d = new Dog();
d.category();

This time the alert reads “canine”.

Many generations

Often a problem with different approaches to Javascript inheritance, here’s how Troels approach deals with it;


function Animal() {
    this.species = "animal";
};

Animal.prototype.category = function() {
    alert(this.species);
};

function Dog() {
    this.Animal();
    this.species += ":dog";
};

// Dog "inherits" from Animal
copyPrototype(Dog, Animal);

function Poodle() {
    this.Dog();
    this.species += ":poodle";
};

// Poodle "inherits" from Dog
copyPrototype(Poodle, Dog);

var p = new Poodle();
p.category();

…alerts: “animal:dog:poodle”

Overriding Parent Methods

By default this approach simply replaces methods. That means you need to make sure you call copyPrototype before assigning any methods to the subclass prototype, otherwise the parent methods will override the child methods;


function Animal() {
    this.species = "animal";
};

Animal.prototype.category = function() {
    alert(this.species);
};

function Dog() {
    this.Animal();
    this.species += ":canine";
};

// Dog "inherits" from Animal
copyPrototype(Dog, Animal);

// Override parent method _after_ calling copyPrototype
Dog.prototype.category = function() {
    alert(this.species.toUpperCase())
    
};

… displays “ANIMAL:CANINE”

It’s also possible, although slightly painful, to call a parent method which has been overridden, with help from apply. Modifying the above Dog.prototype.category method demonstrates this;


Dog.prototype.category = function() {
    // Call overridden parent method...
    Animal.prototype.category.apply(this);
    alert(this.species.toUpperCase())
};

…which results in two alerts. If you needed to pass on method parameters, you’d need to pass the arguments array as the second argument to apply().

Mixins

MixIns (basically multiple inheritance) also works in a fairly predictable fashion;


function Animal() {
    this.species = "animal";
};

Animal.prototype.category = function() {
    alert(this.species);
};

function Quadruped() {};

Quadruped.prototype.run = function() {
    alert('Running...');
}

function Dog() {
    this.Animal();
    this.species += ":canine";
};

// Dog "inherits" from Animal
copyPrototype(Dog, Animal);

// Dog "inherits" from Quadruped
copyPrototype(Dog, Quadruped);

var d = new Dog();
d.category();
d.run();

…two alerts: “animal:canine” and “Running…”

Cautions

Two particular warnings with this approach…

1. When you call copyPrototype matters, as already mentioned. In practice it means you’re best off calling it immediately after declaring a child constructor.

2. Do not declare a toString method for the parent class Function object as this may break the regular expression in copyPrototype. You can still modify a parent prototype without doing any harm though. In other words this will break copyPrototype;


Animal.toString = function() {
    return "this is an animal";
}

But this is OK;


Animal.prototype.toString = function() {
    return "this is an animal";
}

In Summary

Of all the approaches I’ve seen, to me this has become the most convincing – the best way to keep your code DRY without having to modify core Javascript types and introduce strange side effects. It’s also only 8 lines of code, so doesn’t cost much. Credit to Troels for sublime lateral thinking.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • SchizoDuckie

    Peter Nederlof also had some thoughts on this, i think that’s even prettyer…

    http://blogger.xs4all.nl/peterned/archive/2006/01/12/73948.aspx

  • http://www.phppatterns.com HarryF

    Peter Nederlof also had some thoughts on this, i think that’s even prettyer…

    Not bad but have a few problems with Peter’s approach. That it’s modify Function may or may not be a problem (to me it’s a problem). More significant is it fires off parent constructors automatically – what if you don’t want the parent constructor called? Plus is doesn’t support Mixins.

    Of course if you do want to extend Function, you could apply Troels approach in the same way as Peter and have the advantage of not having to reassign the Function object e.g.;

    
    Function.prototype.extends = function(parent) {
        var sConstructor = parent.toString();
        var aMatch = sConstructor.match( /s*function (.*)(/ );
        if ( aMatch != null ) { this.prototype[aMatch[1]] = parent; }
        for (var m in parent.prototype) {
            this.prototype[m] = parent.prototype[m];
        }
    };
    
    // Note not Dog = Dog.extends(Animal)
    Dog.extends(Animal);
    
    

    That way you still have control over the constructor and support for Mixins.

  • kyberfabrikken

    I realized that if the constructor is empty, the regex will fail on ie (works fine at moz). Simply throwing a if (aMatch != null) { around the line which copies the constructor does the trick.

    One more thing. Modifying the prototype actually changes already instantiated objects. Modyfying the parent prototype doesn’t. This might lead to some confusion.

  • http://www.phppatterns.com HarryF

    I realized that if the constructor is empty, the regex will fail on ie (works fine at moz). Simply throwing a if (aMatch != null) { around the line which copies the constructor does the trick.

    That’s one I hadn’t run into. Updated the example re your suggestion.

  • fabio
  • David Flanagan

    I think the use of the regex is a mistake. It is too fragile. It fails if you use anonymous functions like:

    var Animal = function() { this.species = “animal”; }

    Also, I’m not conviced it is that useful. With it, you
    can call the superclass constructor as “this.Animal()”
    Without it you’d use “Animal()” instead.

    I’d suggest reserving a fixed property name, such as superclassConstructor, or just superclass, to hold the reference to the superclass constructor. Then you don’t need to rely on Function.prototype.toString() and regexp hackery to figure out the name of the superclass constructor. You just say:

    descendant.prototype.superclass = parent;

  • Ren

    Really want ecmascript v4..
    Flashs’ actionscript 2.0 is based upon it, QuickTime has it.
    But none of the browsers. :/

    http://livedocs.macromedia.com/flash/8/main/00001870.html

  • http://www.sitepoint.com/ Kevin Yank

    There’s a much simpler way of doing inheritance if you don’t need multiple inheritance (mixins)–which, if you’re used to Java, you’ll instinctively avoid anyway. This approach is described in the link fabio posted above:

    
    function Animal() {
      this.species = 'animal'; 
    }
    
    Animal.prototype.category = function() { 
      alert(this.species); 
    } 
    
    function Dog() {
      this.species += ':dog'; 
    }
    // Dog inherits from Animal 
    Dog.prototype = new Animal();
    
    Dog.prototype.speak = function() {
      alert('Bark!');
    }
    
    function Poodle() {
      this.species += ':poodle'; 
    }
    // Poodle inherits from Dog 
    Poodle.prototype = new Dog();
    
    Poodle.prototype.speak = function() {
      alert('Yip!');
    }
    
    var p = new Poodle(); 
    p.category(); // animal:dog:poodle
    p.speak();    // Yip!
    

    The only disadvantage I see here is that you’re not able to pass different arguments to the superclass’s constructor for each instance of the subclass you create. Am I missing something?

  • http://www.phppatterns.com HarryF

    David:

    It fails if you use anonymous functions like:

    var Animal = function() { this.species = “animal”; }

    That’s a fair point. At the same time I would argue that using anonymous functions this way would only happen if you’re manipulating data / DOM on the fly. In other words this probably wouldn’t be a way to “publish” an API for other programmers to use and unlikely you’d be wanting to extend it (perhaps it might inherit from something else but I doubt vice versa).

    There might also be issues with trying to extend build in classes – if I remember right IE doesn’t regard RegExp to be a class in the same way as Mozilla.

    All that said and I know that regex looks very hacky but, under normal circumstances it’s going to do the right thing. Effectively it’s filling in for what typeof “fails” to do with user defined Objects.

    David:

    I’d suggest reserving a fixed property name, such as superclassConstructor, or just superclass, to hold the reference to the superclass constructor.

    Guess I’ve got a gut problem with that approach. Part of it is if you’re bringing different scripts together where people have used different conventions and perhaps another is simply too much thinking in terms of classic inheritance – having something so fundamental defined only be convention makes me nervous.

    Kevin:

    The only disadvantage I see here is that you’re not able to pass different arguments to the superclass’s constructor for each instance of the subclass you create. Am I missing something?

    This may sound odd but there is some reason why I didn’t like that approach, after reading it long ago in Javascript: The Definitive Guide, but have forgotten the train of thought that brought me there.

    It’s got something to do with this;

    Poodle.prototype = new Dog();
    alert(Poodle.prototype.constructor);

    Here the constructor is the Animal constructor. With Troels approach you get to keep the Poodle constructor in the prototype. Quite why thats important though, I’ve long since forgotten ;) Perhaps it just seemed like a nasty side-effect. Will get back if I think of it.

  • http://www.sitepoint.com/ Kevin Yank

    It’s got something to do with this;

    Poodle.prototype = new Dog();
    alert(Poodle.prototype.constructor);

    Here the constructor is the Animal constructor.

    Hmm yeah. It’s a little counter-intuitive (but then what about prototypes is intutive?), but I don’t see what problems this could cause either.

    In particular, why ask for Poodle.prototype.constructor when you can just ask for Poodle? If your goal is to be able to access the constructor from an instance, well that’s a different story. But like yourself, I can’t think of a situation where you would need to.

  • http://www.phppatterns.com HarryF

    In particular, why ask for Poodle.prototype.constructor when you can just ask for Poodle? If your goal is to be able to access the constructor from an instance, well that’s a different story. But like yourself, I can’t think of a situation where you would need to.

    Still pondering and so far the only real reason I can think of is when you need to work out what user defined class an instance was created from like;

    var MsTibbles = new Poodle();
    
    // ... later
    
    if ( MsTibbles.constructor == Poodle ) {
    

    That’s something you need in the absence of “instanceof” but that may no longer be an issue these days – I don’t know the history of various ECMAScript implementations and when instanceof was supported, but it’s in Firefox 1.5 and seems of have been implemented in “Javascript 1.4″.

    Otherwise nice link here discussing some of this.

    Anyway – it’s now bugging me ;)

  • David Flanagan

    HarryF wrote:

    That’s a fair point. At the same time I would argue that using anonymous functions this way would only happen if you’re manipulating data / DOM on the fly. In other words this probably wouldn’t be a way to “publish” an API for other programmers to use and unlikely you’d be wanting to extend it (perhaps it might inherit from something else but I doubt vice versa).

    Actually, anonymous functions are probably even more common in production library code that is published. That is because it is good practice to put it in a namespace. For example:

    var com = {};
    com.davidflanagan = {};
    com.davidflanagan.Animal = function() { ... }
    

    This kind of namespacing is standard with module libraries such as JSAN and (I think) Dojo. Your code won’t interoperate with code from those repositories.

  • http://www.phppatterns.com HarryF

    This kind of namespacing is standard with module libraries such as JSAN and (I think) Dojo. Your code won’t interoperate with code from those repositories.

    That’s a very good point that I hadn’t considered. I guess it would be possible to support that in a different implementation, where you pass a string identifying the parent rather than a reference to the function object – something like;

    
    function copyPrototype(descendant, parent) {
        var aMatch = parent.match( /([^.]+)$/ );
        parent = eval(parent);
        descendant.prototype[aMatch[1]] = parent;
        for (var m in parent.prototype) {
            descendant.prototype[m] = parent.prototype[m];
        }
    };
    
    copyPrototype(Dog, "myns.Animal");
    
    

    But that’s starting to look very hacky and there’s probably more cases there I haven’t considered.

    Anyway – thanks for pointing that out.

  • http://www.calcResult.co.uk omnicity

    Can I just mention that all of the code samples in this article are disappearing as soon as the page is loaded when I view this in IE 6.0 on WinXP Pro?
    Not my first choice of browser or OS, but this is a corporate build!

  • http://www.calcResult.co.uk omnicity

    At the same time I would argue that using anonymous functions this way would only happen if you’re manipulating data / DOM on the fly. In other words this probably wouldn’t be a way to “publish” an API …

    On the contrary, I recall reading only a few days ago (can’t remember where) that anonymous functions were a good way of simulating Java’s ‘Private’ access modifier, since it prevented third parties calling such functions easily.

    On a seperate note, I can’t see why you would go to all of the bother of setting up inheritance like this, then choose to not use it occassionally, as was suggested. A poodle is always a dog, and an animal, so if this feature is needed it suggests to me that the object model has been badly designed.

  • http://arielladog.tripod.com Arielladog

    In general, I don’t really trust anything that relies on string manipulation and string manipulation isn’t known to be extremely fast (though in this case, that code doesn’t actually run too much).

    I think Kevin Yank’s implementation is fine and the .constructor problem is the exact one addressed by KevLinDev’s article.

    I think this implementation is interesting because it’s conceptually better because when inheriting from objects, it just copies their “.prototype” properties over rather than assign their prototype to a new object (Dog.prototype = new Animal()). Hence, as Kevin points out, you can call a constructor with parameters. I would argue that it offers other benefits b/c the descendant’s methods don’t point to a random superclass object but instead do the method/property lookup correctly via the proto-chain. However, in order to do this, you have to loop through every property on the superclass’s .prototype object, which could be a little slow (but it’s only done once so not a big deal).

  • kyberfabrikken

    David Flanagan makes a very relevant point.

    A client asked me to whisk some thick client dhtml together in a hurry (basically as netvibes.com clone), so I took a deeper look at some of the emerging javascript frameworks.
    The copyPrototype as shown by harry doesn’t work with name.space.foo = function … style, which is rather annoying.
    Even if it worked, the constructor contains dots in it’s name, so you can’t really create a function by the same name.

    Anyway – As harry describes, calling overridden methods is possible through the magic of a little known construct called apply. This same construct can be used to call parent constructors. It may seem a bit clunky, but if you ever used PHP4 to write OO code, you’ll recognize that you are essentially calling a static method from within an object instance – works the same way.

    To conclude, the following works :

    
    assert = function(b) {
    	if (!b) throw new Error('Assertion failed');
    }
    try {
    copyPrototype = function(descendant, parent) {
    	// inherit methods
    	for (var m in parent.prototype) {
    		descendant.prototype[m] = parent.prototype[m];
    	}
    	// inherit parent prototype
    	descendant.prototype.parent = parent.prototype;
    };
    
    // demonstrates calling overridden method
    var tmp = {};
    tmp.foo = function() {}
    tmp.foo.prototype.test = function() {
    	this._calledBy = 'test';
    }
    tmp.tempest = function() {}
    copyPrototype(tmp.tempest, tmp.foo);
    tmp.tempest.prototype.test = function() {
    	this._calledBy = 'tempest';
    }
    tmp.supertempest = function() {}
    copyPrototype(tmp.supertempest, tmp.tempest);
    tmp.supertempest.prototype.test = function() {
    	this._calledBy = 'supertempest';
    }
    tmp.supertempest.prototype.invokeOverridden = function() {
    	this.parent.parent.test.apply(this, arguments);
    }
    var o = new tmp.supertempest();
    o.invokeOverridden();
    assert(o._calledBy == 'test');
    
    // demonstrates chaining constructors
    var tmp = {};
    tmp.foo = function() {
    	this._foo = true;
    }
    tmp.tempest = function() {
    	this._tempest = true;
    	tmp.foo.apply(this, arguments);
    }
    copyPrototype(tmp.tempest, tmp.foo);
    tmp.supertempest = function() {
    	this._supertempest = true;
    	tmp.tempest.apply(this, arguments);
    }
    copyPrototype(tmp.supertempest, tmp.tempest);
    var o = new tmp.supertempest();
    assert(o._supertempest && o._tempest && o._foo);
    
    alert('test passed');
    } catch (ex) {
    	alert(ex.message);
    }
    

    Once you got used to the .apply(this, arguments) it’s rather harmless, and there is no need for wierd hacks and extending the build-in objects’ prototype.

    PS: omnicity – yes, very annoyingly this page is broken in IE …

  • http://www.sitepoint.com/ Kevin Yank

    Can I just mention that all of the code samples in this article are disappearing as soon as the page is loaded when I view this in IE 6.0 on WinXP Pro?
    Not my first choice of browser or OS, but this is a corporate build!

    Thanks for reporting this! We’re on it…

  • expertseries

    Is it just me or does it seem that the comments are leading straight back to crawford?

    
    'invokeOverridden' =~ 'uber'?
    copyPrototype =~ Fnc.inherits;
    apply =~ apply;
    
    

    Funny that I could never really grasp crawford’s approach until reading through this thread; copying, testing and renaming the examples (to ‘inherits’ no less).. only to re-read crawford to find this:

    
    Function.method('inherits', function (parent) {
        var d = 0, p = (this.prototype = new parent());
        this.method('uber', function uber(name) {
            var f, r, t = d, v = parent.prototype;
            if (t) {
                while (t) {
                    v = v.constructor.prototype;
                    t -= 1;
                }
                f = v[name];
            } else {
                f = p[name];
                if (f == this[name]) {
                    f = v[name];
                }
            }
            d += 1;
            r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
            d -= 1;
            return r;
        });
        return this;
    });
    
  • Pingback: Le blog » Archive du blog » Javascript orienté Objet

  • bobippolito

    MochiKit doesn’t have an approach to inheritance. The *only* inheritance in MochiKit is to create the various Error constructors so that “instanceof Error” can be used to detect one (useful for Deferreds), and that does inheritance in the idiomatic JavaScript way.

    Everything else in MochiKit uses more functional patterns. In my experience with languages like Python is that you really just don’t need inheritance for much, and that’s four times as true in JavaScript.

    I’m not entirely sure what you mean by the 60kloc reference. MochiKit is less than 8kloc in total with comments, and Base is less than 1.5. The functionality in Base is pretty shallow — it’s mostly the minimum required functionality in order to make the rest of MochiKit possible. If you were to have your way, what would be there? Or more importantly, what *wouldn’t*?

    MochiKit originally was going to have an inheritance method, but it turned out to be YAGNI. I wrote a bunch of code that make single inheritance work (while maintaining the functionality of instanceof), but I just didn’t need it at all in any production or library code.. so I tossed it. Someone else was interested in it, so it lives on here though:
    http://openjsan.org/doc/r/rk/rkinyon/Class/0.05/lib/Class.html

  • james.estes

    I recently had an idea about this and was wondering what your thoughts were. The implementation is as follows:

    
    Class.extend = function(SubClass, SuperClass){
        var inlineSuper = function(){};
        inlineSuper.prototype = SuperClass.prototype;
        SubClass.prototype = new inlineSuper();
        SubClass.prototype.constructor = SubClass;
    }
    

    I like it because I can build a nice prototype chain without calling the SuperClass constructor JUST to get the inheritance (gets messy if the constructor actually does something or requires args). It also gets around the obj.constructor problem.

    This doesn’t allow (directly) for multiple inheritance, but it could also be used in conjunction with a class augmentation/copy approach (and I tend to shy away from multiple inheritance anyway).

    I’ve posted the idea on my blog at http://www.itsalleasy.com/2006/02/05/prototype-chain/

  • Pingback: Sascha Goebels WebLog » Blog Archive » Javascript Inheritance

  • Chris Barber

    I’ve come up with a way of doing inheritance that suites my needs. I created a helper function Class() that builds the class based on objects passed in. It’s super simple to use and the code is clean. I’ve posted code and details on my blog:

    http://ambientreality.blogspot.com/2006/03/javascript-inheritance.html

    Feedback is welcome.

  • John Barry

    I beleive inheritance is most easily acheived using the following:

    
    MyClass1 = function(param1){
    this._privMember = param1;
    };
    
    MyClass1.prototype.method1 = function(a, b){
    ...
    };
    
    
    SubMyClass2 = function(param1){
    MyClass.apply(this, arguments); 
    //parameters passed to superclass and private members of superclass available to sub class
    };
    
    SubMyClass2.prototype = new MyClass1();
    SubMyClass2.prototype.constructor = SubMyClass2;
    
    SubMyClass2.prototype.method1 = function(a,b){
    //use private members of superclass or subclass
    
    //call the superclass method using
    MyClass1.prototype.method1.call(this, a, b);
    }
    
    

    Any comments to johnny_barry@hotmail.com
    The ideas above could be packaged into functions but I think it is better to get use to how ecmascript works. Function.prototype.call() and Function.prototype.apply() are great functions!

  • Pingback: A Base Class for JavaScript Inheritance

  • Pingback: Ajaxian » Dean Edwards and Another Base.js

  • Pingback: wanderingken.com » Extending Prototype : Class.extend()

  • Pingback: Twologic » Blog Archive » Ruby OO Continued…

  • Pingback: Twologic » Blog Archive » Javascript OO Ruby Style

  • Alex Le

    Everyone, the above code of copyPrototype() in the article will NOT work in Internet Explorer (6.0) but works just fine in Firefox up to 1.5.0.4 in this following case:

    
    function Animal () {//code goes here } // notice the space between Animal and the left paranthesis
    function Dog (){  this.Animal(); }   // this will generate error in IE
    copyPrototype( Dog, Animal); //
    
    

    The reason is that the regexp in copyPrototype used to match the parent’s constructor will also match the space after (and before) the constructor’s name. Hence instead of grabbing “Animal” only, the pattern will also grab “Animal ” instead. Firefox, however, resolve this just fine. IE, on the other hand, will give out a nasty and almost unidentifiable result in the call this.Animal() in the Dog’s constructor. This bug took me almost 2 days to slowly work through and discover.

    So here is the new fix snippet of copyPrototype() that will work with any type of function declarations:

    
    function copyPrototype(descendant, parent) {
        var sConstructor = parent.toString();
        var aMatch = sConstructor.match( /s*function (.*)s*(/ );
    	
        var sConstructor = parent.toString();
        var aMatch = sConstructor.match( /s*function (.*)(/ );	
    	if ( aMatch != null ) { descendant.prototype[aMatch[1].replace(/^s*|s*$/g,"")] = parent; } 
    		descendant.prototype[ aMatch[1] ] = parent; 
        for (var m in parent.prototype)
            descendant.prototype[m] = parent.prototype[m];
    }
    
    

    What I have added here is

    aMatch[1].replace(/^s*|s*$/g,"") to trim the space before and after function name before the assignment. This updated code has proved to work well in my test cases.

    Cheers!

    Alex Le at http://www.alexle.net

  • Paul Crowley
  • Alexandru Matei

    Hi,

    The single inheritance example below doesn’t need copyPrototype.
    It works fine.

    And is possible to call the base class method which has been overridden.

        function BaseClass(divID) 
        { 
                   
            alert("  Base class constructor"); 
            this.divID=divID;
           
            
            //this method doesn't need to be called from the derived class!
            this.SayHello = SayHello;
            
            function SayHello()
            {
                  alert ("Base class SayHello() '"+this.divID+"'");
            } 
       
      
         //this method must be overridden in the derived class
          BaseClass.prototype.SayGoodbye = function(arg) 
          { 
                alert("Base class SayGoodbye(): '"+this.divID+"' "+arg); 
          }                 
            
    	          
        } 
       
       
       
        function DerivedClass(divID) 
        { 
       
            alert("  Derived class constructor"); 
            
           //call base class constructor          
            BaseClass.call (this,divID); 
              
             //override method 
            DerivedClass.prototype.SayGoodbye = function(arg) 
            { 
                //call the base class version !
                          
                BaseClass.prototype.SayGoodbye.call(this,arg); 
                alert("Derived class SayGoodbye(): '"+this.divID+"' "+arg); 
            } 
               
        } 
    
       var b = new BaseClass("base class"); 
       b.SayGoodbye(102);     
       b.SayHello(); 
    
        var d = new DerivedClass("derived class"); 
        d.SayGoodbye(102);     
        d.SayHello();
  • Alexandru Matei

    Hi,

    Your code would look like this.
    It’s simple and good enough for my needs.
    As said, I’m happy that it doesn’t need copyPrototype and is possible to call the base class method which has been overridden.

    function Animal(type) 
          { 
                alert('Base class constructor'); 
    
    	    this.species = type; 
    	    
    	     //this method doesn’t need to be called from the derived class!
                 this.SayHello = SayHello;
                 
                 function SayHello()
                 {
                     alert ("Base class SayHello() '"+this.species+"'");
                 } 
    	
    	     
    	     //must be overridden  in the derived class
         	     Animal.prototype.Category = function()
    	     { 
    	            alert('Base class Category() ' +this.species); 
    	     }
       	 
     
    	}
    	
             
    	  
    		 
    	function Dog(type) 
    	{ 
                alert('Derived class constructor'); 
    
    	    // Call the base class constructor 
                Animal.call (this,type); 
       
                //override method
      	    Dog.prototype.Category = function() 
    	    { 
    	        //call the base class version !
    	        Animal.prototype.Category.call(this); 
    	        alert("Derived class Category() " +this.species); 
    	    }
         
        }
       
    var d = new Dog('dog'); 
       d.SayHello();
       d.Category();
  • abigdog

    function inherit(descendant, parent) {
    var sConstructor = parent.toString();
    var aMatch = sConstructor.match( /s*function (.*)(/ );
    if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
    for (var m in parent.prototype) {
    // MY HUMBLE ADDITION
    if (typeof(parent.prototype[m]) == ‘function’) {
    descendant.prototype[aMatch[1]+’_’+m] = parent.prototype[m];
    }
    descendant.prototype[m] = parent.prototype[m];
    }
    }

    my humble addition allows parent methods to be called without using “apply”.

    if B extends A as in Mr. Fuecks examples, and “obj” is an instance of A, and “category” a virtual function, class A’s version can be invoked on obj as “obj.A_category()” similar to the c++ syntax “obj->A::category()”

  • M

    Hi,
    I have tried an different techniques related to JavaScript inheritance subject.
    The code and the explanation are to long to post them here so if anyone is interested to take a look over it you can find it at http://www.dotnetcaffe.net under JavaScript category. Fell free to criticize the code in any way you want…just don’t flame :).

  • Nisha

    Such a helpful link for javascript inheritance concept

  • Arunoda Susiripala

    A new Way of copyPrototype method

    hello when i'm reading this document i was clueless about the copyProtype method..because it's really hard to get the meaning of that...

    So i've remodified it with just 2 lines of codes with a more robustness...

    function inherit(Child,Parent){
    Child.prototype=new Parent();
    Child.prototype['super']=Parent;
    }

  • Arunoda Susiripala

    A new Way of copyPrototype method

    hello when i'm reading this document i was clueless about the copyProtype method..because it's really hard to get the meaning of that...

    So i've remodified it with just 2 lines of codes with a more robustness...

    function inherit(Child,Parent){
    Child.prototype=new Parent();
    Child.prototype['super']=Parent;
    }

    Now what you’ve to do is just call inherit method and call this.super() in your Child class….

    here is complete solution….

    function inherit(Child,Parent){
    Child.prototype=new Parent();
    Child.prototype['super']=Parent;
    }

    function Phone(no){
    this.no=no;
    this.callTo=function(oNo){
    alert("calling " + this.no + " to " + oNo );
    }
    }

    function VideoPhone(no){
    this.super(no);
    this.no="Video: " + this.no;
    }

    inherit(VideoPhone,Phone);

    var phone=new VideoPhone("0718360974");
    phone.callTo("0098");