I have a replacement for class User ...
as a factory function below:
const user = (name, age) => {
return {
name: name,
age: age,
}
}
I have an admin
, too, that I would normally extend
using ES6 classes. How would I do this using spread to give admin
the properties of user
as well?
const admin = (level) => {
return {
level: level,
}
}
The general approach when using factory functions is one of composition. This is what takes the place of inheritance. To compose two different objects together, you could easily just spread the object props, like Eric Elliott's functional mixin approach:
const user = (name, age) => ({ name, age })
// The mixin approach
const withAdminLevel = (level, user) => ({ ...user, level })
console.log(withAdminLevel(1, user('John Doe', 30)))
From that idea, though, we could also just use the user()
factory function from inside admin()
, instead of passing in a user. This could simplify your calls, but may not be as desirable in some cases (Ex. when you need to "upgrade" a user):
const user = (name, age) => ({ name, age })
// Use "user" factory function inside to simplify calls
const admin = (level, ...args) => ({ ...user(...args), level })
console.log(admin(1, 'John Doe', 30))
Finally, we can combine these two:
const user = (name, age) => ({ name, age })
// The mixin approach
const withAdminLevel = (level, user) => ({ ...user, level })
// Use "user" factory function inside to simplify calls
const admin = (level, ...args) => withAdminLevel(level, user(...args))
const existingUser = user('John Doe', 30)
console.log(withAdminLevel(1, existingUser)) // upgrade
console.log(admin(2, 'Jane Doe', 28)) // still simple to do