I have Define a "Animal" prototype object with:
2 properties: name, age and 1 function: sound, I need to create the following objects which are extended from "Animal": Cow, Sheep, Cat (I can use any name and age), then overriding the function "sound" to represent each specific sound of each animal for example:
I have to use console.log to print the following result:
Name and Age of each type of animal and the sound of each type of animal
I already composed this:
const Animal = {
Cow: {
name: "Peppa",
age: 12,
sound: function cowSound() {
alert("Moo!");
}
},
Sheep: {
name: "Shirley",
age: 7,
sound: function sheepSound() {
alert("Baa!");
}
},
Cat: {
name: "Felipe",
age: 3,
sound: function catSound() {
alert("Meow!");
}
},
};
console.log(JSON.stringify(Animal))
But the result is this: "{"Cow":{"name":"Peppa","age":12},"Sheep":{"name":"Shirley","age":7},"Cat":{"name":"Felipe","age":8}}"
Which is pretty ugly I must admit
How can I display the way I need it with JSON Stringify and see why the sound it's not displaying here, thanks in advance
You can use OLOO (Object linked to other objects) pattern to achieve the inheritance using Object.create method.
const Animal = {
init: function(name, sound) {
this.name = name;
this.sound = sound;
},
makeSound: function() {
console.log(`${this.name} has the sound "${this.sound}"`);
},
};
// inheritance via Object.create
const Cow = Object.create(Animal);
const Sheep = Object.create(Animal);
const Cat = Object.create(Animal);
// any other methods specific to Cat
Cat.purr = function() {
conslo.log(`${this.name} "purrs"`);
};
const animals = [];
// initializing objects
var cow = Object.create(Cow);
cow.init("Cow", "moop");
animals.push(cow);
var sheep = Object.create(Sheep);
sheep.init("Sheep", "bee");
animals.push(sheep);
var cat = Object.create(Cat);
cat.init("Cat", "meow");
animals.push(cat);
// printing
animals.forEach((animal) => {
animal.makeSound();
});
Javascript does not have classes actually, it has only the functions. ES6 class syntax gets transpiled into prototype chained functions like below. @oerol has provided an answer using JS classes.
Read Inheritance and the prototype chain
function Animal(name, sound) {
this.name = name;
this.sound = sound;
}
Animal.prototype.makeSound = function() {
console.log(`${this.name} has the sound "${this.sound}"`);
};
// inheritance via prototype chaining
function Cow(name, sound) {
Animal.call(this, name, sound);
}
Cow.prototype = Object.create(Animal.prototype);
function Sheep(name, sound) {
Animal.call(this, name, sound);
}
Sheep.prototype = Object.create(Animal.prototype);
function Cat(name, sound) {
Animal.call(this, name, sound);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.purr = function() {
conslo.log(`${this.name} "purrs"`);
};
// initializing new objects
const animals = []
var cow = new Cow("Cow", "mooo");
animals.push(cow)
var sheep = new Sheep("Sheep", "bee");
animals.push(sheep)
var cat = new Sheep("Cat", "meow");
animals.push(cat)
// printing
animals.forEach((animal) => {
animal.makeSound();
});
You can do console.log(Animal) if you want it to be more readable.
However, as @Barmar pointed out, that is not the correct way to instantiate a class. A more suitable approach would be:
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
sound() {
alert("Make Sound");
}
}
class Cow extends Animal {
sound() {
alert("Moo!");
}
}
class Sheep extends Animal {
sound() {
alert("Meh!");
}
}
class Cat extends Animal {
sound() {
alert("Miau!");
}
}
let cow = new Cow("Peppa", 12) // Create a new object
cow.sound() // "Moo!"
console.log(cow) // Cow { name: 'Peppa', age: 12 }