defaultable.js
function merge_obj(high, low) {
  if(!is_obj(high))
    throw new Error('Bad merge high-priority');
  if(!is_obj(low))
    throw new Error('Bad merge low-priority');

  var keys = [];
  function add_key(k) {
    if(!~ keys.indexOf(k))
      keys.push(k);
  }

  _each(_keys(high), add_key);
  _each(_keys(low), add_key);

  var result = {};
  _each(keys, function (key) {
    var high_val = high[key];
    var low_val = low[key];

    if(is_obj(high_val) && is_obj(low_val))
      result[key] = merge_obj(high_val, low_val);
    else if (key in high)
      result[key] = high[key];
    else if (key in low)
      result[key] = low[key];
    else
      throw new Error('Unknown key type: ' + key);
  })

  return result;
}
function merge_obj(high, low) {
  if(!is_obj(high))
    throw new Error('Bad merge high-priority');
  if(!is_obj(low))
    throw new Error('Bad merge low-priority');

  var keys = [];
  function add_key(k) {
    if(!~ keys.indexOf(k))
      keys.push(k);
  }

  _each(_keys(high), add_key);
  _each(_keys(low), add_key);

  var result = {};
  _each(keys, function (key) {
    var high_val = high[key];
    var low_val = low[key];

    if(is_obj(high_val) && is_obj(low_val))
      result[key] = merge_obj(high_val, low_val);
    else if (key in high)
      result[key] = high[key];
    else if (key in low)
      result[key] = low[key];
    else
      throw new Error('Unknown key type: ' + key);
  })

  return result;
}
function merge_obj ( high , low ) { if ( ! is_obj ( high ) ) throw new Error ( 'Bad merge high-priority' ) ; if ( ! is_obj ( low ) ) throw new Error ( 'Bad merge low-priority' ) ; var keys = [ ] ; function add_key ( k ) { if ( ! ~ keys . indexOf ( k ) ) keys . push ( k ) ; } _each ( _keys ( high ) , add_key ) ; _each ( _keys ( low ) , add_key ) ; var result = { } ; _each ( keys , function ( key ) { var high_val = high [ key ] ; var low_val = low [ key ] ; if ( is_obj ( high_val ) && is_obj ( low_val ) ) result [ key ] = merge_obj ( high_val , low_val ) ; else if ( key in high ) result [ key ] = high [ key ] ; else if ( key in low ) result [ key ] = low [ key ] ; else throw new Error ( 'Unknown key type: ' + key ) ; } ) return result ; }
Recursively merge higher-priority values into previously-set lower-priority ones.
Recursively merge higher - priority values into previously - set lower - priority ones .