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:
- Cow has the sound "mooo"
- Sheep has the sound "bee" sheep sound
- Cat has the sound "meow"
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
CodePudding user response:
Using OLOO pattern
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();
});
Using prototype chaining
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();
});
CodePudding user response:
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 }