1

This is my JavaScript code:

function animal(){
    var animal_sound;
    this.animal = function(sound){
        animal_sound = sound;
    }

    this.returnSound = function(){
        return animal_sound;
    }
}

function cat(){
    this.cat = function(sound){
        this.animal(sound);
    }
}
cat.prototype = new animal()
cat.prototype.constructor = cat;

//Create the first cat
var cat1 = new cat();
cat1.cat('MIAO');//the sound of the first cat

//Create the second cat
var cat2 = new cat();
cat2.cat('MIAAAAUUUUUU');//the sound of the second cat

alert(cat1.returnSound()+' '+cat2.returnSound());

Simply I have the cat function that extend the animal function. Than I have created two different cats (cat1 and cat2). Each cat has the own sound but when I print their sounds I obtain:

MIAAAAUUUUUU MIAAAAUUUUUU

The cat2 sound overwrite the cat1 sound and I would not want this.

I would like to obtain:

MIAO MIAAAAUUUUUU

Can anyone help me?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Fabio
  • 15
  • 2

2 Answers2

0

That's because you are setting the prototype up with

cat.prototype = new animal()

Each animal instance has its own "private" animal_sound variable, but all cat instances inherit from the same animal instance and thus they "share" this variable.

Instead you should invoke the animal for each cat instance:

function cat(){
    animal.call(this);

    this.cat = function(sound){
        this.animal(sound);
    }
}

You don't even need to assign anything to cat.prototype in this case. However, if you plan to add methods to the prototype (which you should), use Object.create to set up inheritance. More info here: Benefits of using `Object.create` for inheritance.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

The animal() and .returnSound() methods are on the prototype, and so they're shared between all instances of cat.

Because they were created in the animal constructor, and uses a variable in that constructor's scope, every time you call .animal(), you're overwriting the same variable that is used by .animal() and .returnSound().

To do what you want, you'll need to create a new .animal() and .returnSound() method for each cat.


function animal(){
    var animal_sound;
    this.animal = function(sound){
        animal_sound = sound;
    }

    this.returnSound = function(){
        return animal_sound;
    }
}

function cat(){
    animal.call(this); // apply the `animal()` function to the new `cat` object
    this.cat = function(sound){
        this.animal(sound);
    }
}
cat.prototype = new animal()
cat.prototype.constructor = cat;

Now when you create the cats, they'll have their own .animal() and .returnSound() methods, which will be created in a separate invocation of animal for each cat, so there will be a new animal_sound for each of those pairs of methods.

var cat1 = new cat();
cat1.cat('MIAO');

var cat2 = new cat();
cat2.cat('MIAAAAUUUUUU');

alert(cat1.returnSound()+' '+cat2.returnSound()); // MIAO MIAAAAUUUUUU

Of course, in doing this, you're not taking much advantage of prototypal inheritance.

user2736012
  • 3,543
  • 16
  • 13