code: function filter(obj, keys, recurse) {
    if (typeof obj !== 'object') { throw new TypeError('obj must be an object'); }
    if (!Array.isArray(keys)) { throw new TypeError('keys must be an array'); }
  
    if (recurse == null) {
      recurse = false;
    }
    if (typeof recurse !== 'boolean') { throw new TypeError('recurse must be a boolean'); }
  
    var result;
    if (Array.isArray(obj)) {
      result = [];
    } else {
      result = {};
    }
  
    Object.keys(obj).forEach(function(key) {
      if (~keys.indexOf(key)) { return; }
  
      // recurse if requested and possible
      if (recurse && obj[key] != null && typeof obj[key] === 'object' && Object.keys(obj[key]).length) {
        result[key] = filter(obj[key], keys, recurse);
      } else {
        result[key] = obj[key];
      }
    });
  
    return result;
  }
docs: Filter certain keys from an object without side-effects, optionally recurse.
  
  @param {Object|Array} obj  object to filter keys from
  @param {Array} keys  array of key names to filter
  @param {Boolean, default: false} recurse  whether or not to recurse
  @return {Object} object same as input but without the specified keys