A javascript design pattern for options with default values?
Solution 1:
This uses jQuery.extend but could be interchanged with an object merger from your library of choice or Object.assign in ES6.
function Module(options){
var defaults = {
color: 'red'
};
var actual = $.extend({}, defaults, options || {});
console.info( actual.color );
}
var a = new Module();
// Red
var b = new Module( { color: 'blue' } );
// Blue
Edit: Now also in underscore
or lodash
!
function Module(options){
var actual = _.defaults(options || {}, {
color: 'red'
});
console.info( actual.color );
}
var a = new Module();
// Red
var b = new Module( { color: 'blue' } );
// Blue
In Javascript ES6 you can use Object.assign:
function Module(options = {}){
let defaults = {
color: 'red'
};
let actual = Object.assign({}, defaults, options);
console.info( actual.color );
}
Solution 2:
Using the ES2018 spread syntax for object properties:
const defaults = { a: 1, b: 2 };
const ƒ = (given = {}) => {
const options = { ...defaults, ...given };
console.log(options);
};
Using ES6/ES2015 features, several more options are available.
Using destructuring assignment:
const { a = 1, b = 2 } = options;
You can also use destructuring function parameters:
const ƒ = ({a = 1, b = 2, c = 3} = {}) => {
console.log({ a, b, c });
};
Using Object.assign
:
options = Object.assign({}, defaults, options);
No dependencies!
Solution 3:
To get default options without additional dependencies, I use the following pattern:
var my_function = function (arg1, arg2, options) {
options = options || {};
options.opt_a = options.hasOwnProperty('opt_a') ? options.opt_a : 'default_opt_a';
options.opt_b = options.hasOwnProperty('opt_b') ? options.opt_b : 'default_opt_b';
options.opt_c = options.hasOwnProperty('opt_c') ? options.opt_c : 'default_opt_b';
// perform operation using options.opt_a, options.opt_b, etc.
};
Although a bit verbose, I find it easy to read, add/remove options and add defaults. When there are LOTS of options, a slightly more compact version is:
var my_function = function (arg1, arg2, options) {
var default_options = {
opt_a: 'default_opt_a',
opt_b: 'default_opt_b',
opt_c: 'default_opt_c'};
options = options || {};
for (var opt in default_options)
if (default_options.hasOwnProperty(opt) && !options.hasOwnProperty(opt))
options[opt] = default_options[opt];
// perform operation using options.opt_a, options.opt_b, etc.
};