0

I'm trying to teach myself javascript inheritance.
I have created the following code and try to make it work (After reading some related posts around here).
I must use cross browser syntax and want to use only pure js.
How can I fix the following code?

Update: (After Bergi remarks, Now fully working...)

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Tests</title>
<script type="text/javascript">
    function Animal(name)
    {
        alert("animal ctor " + name);
        this.animalName = name;
    };

    //Base implementation
    Animal.prototype.move = function()
    {
        alert("I am walking");
    };

    //Base implementation
    Animal.prototype.makeVoice = function ()
    {
        alert("Not implemented");
    };

    Animal.prototype.introduce = function ()
    {
        alert("This is " + this.animalName);
    };

    function Bird(name)
    {
        alert("bird ctor " + name);
        Animal.call(this, name);

        //Derived only
        this.standOnWire = function ()
        {
            alert("I'm standing on an electricity wire");
        };
    };

    Bird.prototype = new Animal();
    Bird.prototype.constructor = Bird;

    //Override
    Bird.prototype.move = function()
    {
        alert("I am flying");
    };

            //Override
    Bird.prototype.makeVoice= function ()
    {
        alert("twit twit");
    };

    function Cow(name)
    {
        alert("cow ctor " + name);
        Animal.call(this, name);

        //Derived only
        this.produceMilk = function ()
        {
            alert("I am producing milk");
        };
    };

    Cow.prototype = new Animal();
    Cow.prototype.constructor = Cow;

    //Override
    Cow.prototype.makeVoice = function ()
    {
        alert("mmmooooooo");
    };

    function runCowTests()
    {
        alert('runCowTests');

        var cow1 = new Cow('Cow');

        cow1.introduce();
        cow1.move();
        cow1.makeVoice();
        cow1.produceMilk();
    };

    function runBirdTests()
    {
        alert('runBirdTests');

        var bird1 = new Bird('Canary');

        bird1.introduce();
        bird1.move();
        bird1.makeVoice();
        bird1.standOnWire();
    };
  </script>
 </head>
 <body>
     <input type="button" value="bird tests" onclick="runBirdTests();" />
     <input type="button" value="cow tests" onclick="runCowTests();" />
 </body>
</html>
Yaron
  • 2,209
  • 3
  • 18
  • 33
  • The following answer may be helpful to you: http://stackoverflow.com/a/16063711/1641941 – HMR Feb 24 '14 at 01:29

1 Answers1

3

How can I fix the following code?

A few things:

  • move the assignments to the prototype outside the constructor!
  • myName is superfluous, just use the already existing variable name as it is
  • self is superfluous, just use this
  • the .call() method is spelled lowercase
  • use ….prototype = Object.create(Animal.prototype) - see Correct javascript inheritance
  • you're assigning undefined, the result of the IEFEs, to runCowTests and runBirdTests - not sure whether that is on purpose

function Bird(name) { 
    Animal.call(self, name);
}
// put this first
Bird.prototype = Object.create(Animal.prototype);
// Don't:
// Bird.prototype = {…} - overwrites above assignment

// Derived only
Bird.prototype.standOnWire = function () {
    alert("I'm standing on an electricity wire");
};
// Override
Bird.prototype.move = function () {
    alert("I am flying");
};
// Override
Bird.prototype.makeVoice = function () {
    alert("twit twit");
};
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • @Yaron: `Object.create` is from 2009! And supported since IE9, btw. If you need to support any outdated engines, you still can include the [polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill) and use it without problems. – Bergi Feb 23 '14 at 21:47
  • Bergi can you please take a look at the fixed code and give me a hint about what is still wrong with it? Thank you so much! – Yaron Feb 24 '14 at 10:29
  • You still haven't fixed #5, also you cannot use an object literal as it would overwrite that, and you need to put the property assignments to the prototype after the `Object.create` – Bergi Feb 24 '14 at 12:06
  • My real project must support IE8 so I can't use Object.create. What do you mean by object literal? What are property assignments to prototype? Can you give me please example? – Yaron Feb 24 '14 at 12:43
  • As I said above, you can use the very simple polyfill. – Bergi Feb 24 '14 at 12:45