function forEach(obj, fn, {allOwnKeys = false} = {}) {
  // Don't bother if no value provided
  if (obj === null || typeof obj === 'undefined') {
    return;
  }

  let i;
  let l;

  // Force an array if not already something iterable
  if (typeof obj !== 'object') {
    /*eslint no-param-reassign:0*/
    obj = [obj];
  }

  if (isArray(obj)) {
    // Iterate over array values
    for (i = 0, l = obj.length; i < l; i++) {
      fn.call(null, obj[i], i, obj);
    }
  } else {
    // Iterate over object keys
    const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
    const len = keys.length;
    let key;

    for (i = 0; i < len; i++) {
      key = keys[i];
      fn.call(null, obj[key], key, obj);
    }
  }
}
Iterate over an Array or an Object invoking a function for each item.

If `obj` is an Array callback will be called passing
the value, index, and complete array for each item.

If 'obj' is an Object callback will be called passing
the value, key, and complete object for each property.

@param {Object|Array} obj The object to iterate
@param {Function} fn The callback to invoke for each item

@param {Boolean} [allOwnKeys = false]
@returns {any}