I watched a tutorial on composition, and it makes you compose objects like this:
const eater = (state) => ({
eat(amount) {
console.log(state.name + ' is eating');
state.energy += amount;
}
});
// using a factory
const Dog = (name, energy, breed) => {
let dog = {
name,
energy,
breed
};
return Object.assign(dog, eater(dog));
};
const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20
I was wondering if you could do something like that instead, and if there are any downsides to doing it like that:
const eater = {
eat(amount) {
console.log(this.name + ' is eating');
this.energy += amount;
}
};
const Dog = (name, energy, breed) => {
let dog = {
name,
energy,
breed,
...eater
};
return dog;
};
const leo = Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20
As you can see, instead of creating and assigning a function to the object, with Object.assign, I create another object eater with a method, then I spread that eater object and add it to the dog object being created inside the factory.
So, is there anything wrong with doing it like that?
Thank you!
These two approaches are very similar. Both are workable & good ways.
Here are the differences:
The first approach: eater is a factory function
eater object and eat function is created for each dogeat method is bound:
let leoEat = leo.eat;
leoEat(10); //works
The second approach: eater is an object
eater object and the eat function are reusedeat isn't bound:
const leo = Dog('Leo', 10, 'Pug');
const animal = {name: 'Animal', energy: 0};
leo.eat.call(animal, 30); // Animal is eating
console.log(animal.energy); // 30
console.log(leo.energy); // 10
The third approach (yes, there is!): Eater and Dog are classes
eat function is reusedeat isn't boundclass Eater {
eat(amount) {
console.log(this.name + ' is eating');
this.energy += amount;
}
};
class Dog extends Eater{
constructor (name, energy, breed) {
super();
Object.assign(this, {
name,
energy,
breed
})
}
};
const leo = new Dog('Leo', 10, 'Pug');
leo.eat(10); // Leo is eating
console.log(leo.energy); // 20
console.log(leo instanceof Dog) //true
console.log(leo instanceof Eater) //true