Skip to content

Instantly share code, notes, and snippets.

@ericelliott
Last active May 7, 2023 13:52
Show Gist options
  • Save ericelliott/f3c2a53a1d4100539f71 to your computer and use it in GitHub Desktop.
Save ericelliott/f3c2a53a1d4100539f71 to your computer and use it in GitHub Desktop.
ES6 defaults / overrides pattern

ES6 Defaults / Overrides Pattern

Combine default parameters and destructuring for a compact version of the defaults / overrides pattern.

function foo ({
    bar = 'no',
    baz = 'works!'
  } = {}) {

  return (`${bar}, ${baz}`);
}

console.log(foo({
  bar: 'yay'
})); // logs 'yay, works!'

Equivalent to ES5:

This bit needs to be polyfilled, Or use $.extend(), _.extend(), lodash/object/assign aka _.assign() or equivalent.

var assign = Object.assign;

var defaults2 = {
    bar: 'no',
    baz: 'works!'
  };

function foo2 (options) {
  var settings = assign({}, defaults2, options),
    bar = settings.bar,
    baz = settings.baz;

  return (bar + ', ' +baz);
}

console.log(foo2({
  bar: 'yay'
})); // logs 'yay, works!'

Gist written for How to Use ES6 for Isomorphic JavaScript Apps

@PhiLhoSoft
Copy link

With deep copy: http://plnkr.co/edit/M7ZlnxLrNhDGyGNuq7eh

var dest = { name: 'Foo', age: 25, driver: true, 
    id: { driverLicense: '88-65', ssn: '1-54-455', other: 'mango' }  };
var src1 = { name: 'Bar', driver: false, address: 'Here and there', 
    id: { driverLicense: undefined, ssn: '2-44-985', pwd: '123' }  };
var src2 = { name: 'Moo', maried: true, age: undefined, address: 'Somewhere', 
    id: { driverLicense: '11-75', ssn: undefined, warcry: 'Kowabunga' } };

var d1 = _.cloneDeep(dest);
var d2 = _.cloneDeep(dest);
var d3 = _.cloneDeep(dest);

od.innerText = JSON.stringify(dest) + '\n' + JSON.stringify(src1) + '\n' + JSON.stringify(src2);

res.innerText = 
  // assign overwrites all properties with successive values, including properties set to undefined
  JSON.stringify(_.assign(dest, src1, src2)) + '\n' + 
  // merge overwrites deeply all properties with successive values, except undefined properties
  JSON.stringify(_.merge(d1, src1, src2)) + '\n' +
  // defaults assigns properties which are undefined: no overwriting of exising properties
  JSON.stringify(_.defaults(d2, src1, src2)) + '\n' +
  // defaultsDeep assigns deeply properties which are undefined: no overwriting of exising properties
  JSON.stringify(_.defaultsDeep(d3, src1, src2));

Result:

Original Data

{"name":"Foo","age":25,"driver":true,
    "id":{"driverLicense":"88-65","ssn":"1-54-455","other":"mango"}}
{"name":"Bar","driver":false,"address":"Here and there",
    "id":{"ssn":"2-44-985","pwd":"123"}}
{"name":"Moo","maried":true,"address":"Somewhere",
    "id":{"driverLicense":"11-75","warcry":"Kowabunga"}}

Result

{"name":"Moo","driver":false,
    "id":{"driverLicense":"11-75","warcry":"Kowabunga"},
    "address":"Somewhere","maried":true}
{"name":"Moo","age":25,"driver":false,
    "id":{"driverLicense":"11-75","ssn":"2-44-985","other":"mango","pwd":"123","warcry":"Kowabunga"},
    "address":"Somewhere","maried":true}
{"name":"Foo","age":25,"driver":true,
    "id":{"driverLicense":"88-65","ssn":"1-54-455","other":"mango"},
    "address":"Here and there","maried":true}
{"name":"Foo","age":25,"driver":true,
    "id":{"driverLicense":"88-65","ssn":"1-54-455","other":"mango","pwd":"123","warcry":"Kowabunga"},
    "address":"Here and there","maried":true}

@ericelliott
Copy link
Author

👍

@vitalets
Copy link

Thanks for the comparison!
For me behavior of _.defaults is most preferable, because it allows to define conditional options with ternary operator that does not overwrite default values:

var src2 = { 
  age: someCondition ? age : undefined 
};
_.defaults(src2, {age: 25}); // {age: 25}

Also for one-level options I've made flat-options package that additionally performs validation of keys and has twice smaller size than _.defaults.

@marcelo-ribeiro
Copy link

👍

@mathieug
Copy link

mathieug commented Mar 5, 2018

Nice trick @ericelliott! How can we name the object parameter if we need an object with all the parameters (given and default)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment