Videos
Lets say I want to create an object that represents a person with the properties name, age, and gender.
Is there any objective reason I should use a class to represent this rather than just making a function `Person()` which creates the object?
You would use Object.create:
const animal = () => ({
talk: function() {
console.log(this.sound);
}
});
const dog = () => Object.create(animal(), {
sound: {
value: "woof"
}
});
// or...
const dog2 = () => {
var someDog = Object.create(animal());
someDog.sound = "woof";
return someDog;
};
var someDog = dog();
someDog.talk();
var someDog2 = dog2();
someDog2.talk();
BTW, my opinion is that you should go with ES2015+ class/inheritance and leave the use of custom factories and Object.create for corner cases where you really need them:
class Animal {
talk() {
return console.log(this.sound);
}
}
class Dog extends Animal {
constructor() {
super();
this.sound = "woof";
}
}
var dog = new Dog();
dog.talk();
I checked this issue because I decided to use Factory Functions instead of classes.
I assume you have a general factory function, like Animal or Mammal, which has some characteristics (such as sound, like some suggested), and you want to inherit them and add some specific characteristic in another factory function.
Let's build an Animal factory function:
const Animal = ({color = "green", numberOfLegs = 4} = {}) => {
const SetColor = (newColor) => {
color = newColor;
};
const GetColor= () => color;
const GetNumberOfLegs = () => numberOfLegs;
const MakeSound = () => console.log("Screetch");
return {
GetColor,
GetNumberOfLegs,
MakeSound
}
}
const newCreature = Animal({color: black, numberOfLegs: 3})
newCreature.MakeSound() // -> "Screetch"
And let's build a Dog factory function:
const Dog = ({name = "rex", color = "black", numberOfLegs = 4} = {}) => {
const MakeSound = () => console.log("Woof Woof");
const Roll = () => console.log(`${name} made a roll!`)
return {
MakeSound,
Roll
}
}
const sniffles = Dog({name: "sniffles", color: black, numberOfLegs: 4})
sniffles.MakeSound() // -> "Woof Woof"
sniffles.Roll() // -> "sniffles made a roll!"
What should I do if I want to inherit all the good things I get from Animal that I have already?
Using ES6 Spread Syntax helps us to achieve a very neat way of doing so:
const Dog = ({name = "rex", color = "black", numberOfLegs = 4} = {}) => {
const anAnimal = Animal({color, numberOfLegs}); // used the Animal factory!
const MakeSound = () => console.log("Woof Woof");
const Roll = () => console.log(`${name} made a roll!`)
return {
...anAnimal, // And That's where magic happens!
MakeSound,
Roll
}
}
const sniffles = Dog({name: "sniffles", color: black, numberOfLegs: 4})
sniffles.GetNumberOfLegs() // -> 4
sniffles.MakeSound() // -> "Woof Woof"
sniffles.Roll() // -> "sniffles made a roll!"
So what actually happened?
In Dog factory we invoked the Animal factory into anAnimal, so anAnimal is now an object.
In the object that Dog factory returns, we spread the anAnimal object, and after that added properties of Dog.
If you give an Object two identical keys with different values, it will take the latter:
const someObject = {a: 1, b: 2, a: 3};
someObject // -> {a: 3, b: 2}
Therefore, you don't need to worry if Dog uses any keys that were given already from Animal, because they are overwritten.