A javascript design pattern for options with default values?
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();// Redvar 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();// Redvar 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 );}
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!
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.};