Michlle95
Michlle95

Reputation: 59

Using spread in factory function instead of class `extends`

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,
    }
}

Upvotes: 2

Views: 299

Answers (1)

BCDeWitt
BCDeWitt

Reputation: 4773

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

Upvotes: 3

Related Questions