2

Please, look at the following way to simulate inheritance in JavaScript. It's very simple and it does not use prototypes at all. It seems to work well, but I suspect something is wrong with it, just because people usually don't do like this. Can anybody explain me, what are disadvantages of this approach and what I am missing? Thanks a lot.

// The base class constructor
function Animal(name)
{
    var _name = name; // local variable, not visible to subclass

    this.greeting = function()
    {
        return "Hello, "+_name;
    }

    this.makeSound = function()
    {
        return "Don't know what to say";
    }
}

// The subclass constructor
function Cow(name)
{
    Animal.call(this, name); // call the base constructor

    this.makeSound = function()  // override base class's method
    {
        return "Mooooo!";
    }
}

var myCow = new Cow("Burenka");

console.log(myCow.greeting());  // call inherited method
console.log(myCow.makeSound()); // call overriden method

UPDATE Thanks to everybody for answers and comments. Just to summarize:

This approach can be used, but there are some limitations:

  • Every instance construction is performed from scratch rather than just setting a link to prototype — this may affect performance.
  • Every instance contains definitions of all the base class's methods — wasting memory.
  • instanceof won't work properly (i.e. won't treat the subclass instance as a base class instance).
  • If you override a method this way, you can not call the implementation from the base class when you need it (if you want just extend the functionality, not replace it completely).
  • If you want to change the implementation of base class's methods dynamically, you need prototypes.

And of course there are other questions here for the same subject. See also:

Community
  • 1
  • 1
C-F
  • 1,285
  • 11
  • 22
  • 2
    Doing it that way you're replicating all methods for all instances, why avoid prototypes? – elclanrs Sep 17 '13 at 21:02
  • 2
    I'm trying to understand what this trend of "without using prototypes" is supposed to be. Prototypes are the foundation of Javascript's OO model. If you want to do OO in Javascript, use prototypes instead of trying to simulate anything. – millimoose Sep 17 '13 at 21:03
  • Your `greeting` method is not inherited, it's assigned in the Anumal constructor. So technically that's not inheritance. – bfavaretto Sep 17 '13 at 21:04
  • Declaring methods inside a Class is fine. Prototyping makes a new instance smaller as prototypes are just a reference and therefore, if you instantiate a class it consumes less memory... (this is just one of many answers) – jsmorph Sep 17 '13 at 21:10
  • Yes, every instance is constructed from scratch. But why is it bad? The effect seems to be the same. Prototypes are good, but there wouldn't be so many questions about them, if they were as clear as classes, right? ;) Everybody tries inventing some simple and reliable way to implement subclassing in JS. This way just seems to be the most short and simple. So what's wrong with it? – C-F Sep 17 '13 at 21:12
  • 1
    Well, you're not doing proper inheritance, you're just extending `this` with another context. You could even do: `var myCow = Cow.call({},"Burenka")`, and it would still work; no inheritance. – elclanrs Sep 17 '13 at 21:17
  • 2
    The prototype chain is how the language implements inheritance, also for its own use. Imagine if JavaScript used your technique instead: every new object would have to have copies of everything in `Object.prototype`; every function would have copies of that, plus everything in `Funcion.prototype`; every string would have their own copy of the `substring` methods & friends, and so on. Not very efficient, right? – bfavaretto Sep 17 '13 at 21:35
  • You forgot to mention that it's harder to implement a Super.call.makeSound in Cow. http://stackoverflow.com/a/16063711/1641941 With prototype you can do Animal.prototype.makeSound.apply(this,arguments) how do you do that without prototype? – HMR Sep 18 '13 at 01:01
  • HMR, good point, thank you. I've updated the post. – C-F Sep 18 '13 at 20:27

1 Answers1

1

In addition to the benefits of defining methods on the prototype described in this answer, with your method an instance of Cow is not an instance of Animal, so you can't use instanceof. With inheritance using prototypes myCow instanceof Animal would give true.

Community
  • 1
  • 1
Andrew Clark
  • 180,281
  • 26
  • 249
  • 286
  • Thank you for the link, I couldn't find that answer. Changing prototype's methods to change the behavior of all instances doesn't look as something widely needed. But you're right about instanceof. Well, let's wait for more answers, maybe there is something else... – C-F Sep 17 '13 at 21:22