Search code examples
javascriptecmascript-6object-composition

Composing object in javascript by passing a list of functionality to a factory function


Using an example from this source

const barker = (state) => ({
  bark: () => console.log('Woof, I am ' + state.name)
})

const driver = (state) => ({
  drive: () => state.position = state.position + state.speed
})

const murderRobotDog = (name)  => {
  let state = {
    name,
    speed: 100,
    position: 0
  }
  return Object.assign(
        {},
        barker(state),
        driver(state)
    )
}

How should I modify this code, to be able to assign functionality based on a parameter passed to the factory function.

For example I could have an array of names like so:

let properties = ["barker", "driver", "killer" etc... ];
murderRobotDog(name, properties);

And it does Object.assign to each of those function names?

I am still learning new syntax, I tried using spread operator like so:

return Object.assign({}, ...properties(state));

Only to come to realization that this is not how any of this works. Can't really figure out how to make a loop out of this either. How should this be done?


Solution

  • You could create a dictionary where the keys form the function names. Then you can just loop over the properties and do the Object.assign:

    const barker = (state) => ({
        bark: () => console.log('Woof, I am ' + state.name)
    });
    
    const driver = (state) => ({
        drive: () => state.position = state.position + state.speed
    });
    
    let types = {
        barker,
        driver
    };
    
    const murderRobotDog = (name, properties) => {
        let state = {
            name,
            speed: 100,
            position: 0
        };
    
        let obj = {};
        for(let prop of properties) {
            Object.assign(obj, types[prop](state));
        }
    
        return obj;
    }
    
    let properties = ["barker", "driver"];
    let result = murderRobotDog('Name', properties);
    console.log(result);
    result.bark()
    

    Output:

    node .\index.js
    { bark: [Function: bark], drive: [Function: drive] }
    Woof, I am Name