What concrete objective advantages do chained functions have vs an options parameter for object initialization?
What do I mean? Well as one example there's a library called dat.GUI that uses the chained function style of setting things up. For example a simple range slider has 4 or 5 parameters.
/**
* @param {object} object The object with a property you want a GUI for
* @param {string} property The name of the property to make a GUI for
* @param {number} min The minimum value
* @param {number} max The maximum value
* @param {number} [step] An optional step
*/
gui.add(object, property, min, max, opt_step)
But then there are a several optional settings. You set them by calling chained functions. For example name(someName)
sets the label shown on the GUI. It defaults to the property name. onChange(fn)
sets a callback when the value changes. listen()
tells the GUI to watch for changes to the property.
So, if you want to set all of those you might write
gui.add(someObject, 'someProp', 10, 20).name('foo').onChange(someFunc).listen();
Where as if gui.add
took an options object as input you could write something like
gui.add({
target: someObject,
property: 'someProp',
min: 10,
max: 20,
name: 'foo',
onChange: someFunc,
listen: true,
});
Is this a 6 of one half dozen of another type of situation as in either style is fine or does one style have concrete benefits over the other.
Off the top of my head
chained functions are more terse but the options parameter is more readable. I see
min: 10
and know that 10 ismin
and notwidth
orsize
ornumItems
etc. Conversely I have to spell out each parameter.options parameters seem more flexible. Can more easily do something like
gui.add(Object.assign({}, globalOptions, localOptions));
Code completion seems like a toss up.
If there are definitions for both the functions and the parameter types including the options parameter then it seems either is similar? Seeing all the options might be useful but completion after
gui.add(...).
it should show the all the chainable functions so that's probably the same?Are options parameter more forward proof?
By that I mean if
giu.add
takes 5 params in a specific order, if it turns out later that parameter #3 is not important but #4 is then it's too late, you can't easily swap the order and make what was parameter #3 optional since all users would have to change their code whereas with options parameters you can?In a strongly typed language if there many options then the options object itself might get large and complicated (lots of initialization for all the fields) whereas with the chained functions you mostly only create what's needed. But, that doesn't fit JavaScript so not an advantage there?
The chained functions can be called later individually
In other words
const control = gui.add(...); ...20 seconds later... control.name('foo');
For the options style you'd need something like
setOptions(options)
method which might not be bad but it might have strange limitations like certain options can only be specified at creation time.
Anything else I'm missing? Is there an objective reason to choose one over the other as in "if situation X use chained functions, if situation Y use an options object" or is it mostly just a style issue?
listen()
return an object? If not then the methods to initialize the object can also be used to change object state and you don't need additional methods for that.