UNPKG

@v4fire/core

Version:
164 lines (127 loc) 2.95 kB
/*! * V4Fire Core * https://github.com/V4Fire/Core * * Released under the MIT license * https://github.com/V4Fire/Core/blob/master/LICENSE */ import extend from 'core/prelude/extend'; /** @see [[ObjectConstructor.forEach]] */ extend(Object, 'forEach', ( obj: unknown, optsOrCb: ObjectForEachOptions | AnyFunction, cbOrOpts?: AnyFunction | ObjectForEachOptions ) => { if (obj == null) { return; } let p: ObjectForEachOptions, cb: AnyFunction; if (Object.isFunction(cbOrOpts)) { cb = cbOrOpts; p = Object.isPlainObject(optsOrCb) ? optsOrCb : {}; } else { if (Object.isFunction(optsOrCb)) { cb = optsOrCb; } else { throw new ReferenceError('A callback to iterate is not specified'); } p = Object.isPlainObject(cbOrOpts) ? cbOrOpts : {}; } const passDescriptor = p.passDescriptor ?? p.withDescriptor; let notOwn: Nullable<boolean | -1>; switch (p.propsToIterate) { case 'all': notOwn = true; break; case 'own': notOwn = false; break; case 'inherited': notOwn = -1; break; default: notOwn = p.notOwn; } if (Object.isString(obj)) { let i = 0; for (const el of obj) { let iterVal: string | PropertyDescriptor = el; if (passDescriptor) { iterVal = { configurable: false, enumerable: true, writable: false, value: el }; } cb(iterVal, i++, obj); } return; } if (typeof obj !== 'object') { return; } if (!passDescriptor && notOwn == null) { if (Object.isArrayLike(obj)) { for (let i = 0; i < obj.length; i++) { cb(obj[i], i, obj); } return; } if (Object.isMap(obj) || Object.isSet(obj)) { for (let o = obj.entries(), i = o.next(); !i.done; i = o.next()) { const [key, el] = i.value; cb(el, key, obj); } return; } if (Object.isIterable(obj)) { let i = 0; for (const el of obj) { if (Object.isArray(el) && el.length === 2) { cb(el[1], el[0], obj); } else { cb(el, i++, obj); } } return; } } if (Object.isTruly(notOwn)) { if (notOwn === -1) { for (const key in obj) { if (Object.hasOwnProperty(obj, key)) { continue; } cb(passDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : obj[key], key, obj); } return; } if (p.withNonEnumerables) { Object.forEach(obj, cb, {withNonEnumerables: true, passDescriptor}); Object.forEach(Object.getPrototypeOf(obj), cb, {propsToIterate: 'all', passDescriptor}); return; } // eslint-disable-next-line guard-for-in for (const key in obj) { const el = passDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : obj[key]; cb(el, key, obj); } return; } const keys = Object[p.withNonEnumerables ? 'getOwnPropertyNames' : 'keys'](obj); for (let i = 0; i < keys.length; i++) { const key = keys[i], el = passDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : obj[key]; cb(el, key, obj); } });