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.
};