| 'use strict'; |
| |
| var isCallable = require('is-callable'); |
| |
| var toStr = Object.prototype.toString; |
| var hasOwnProperty = Object.prototype.hasOwnProperty; |
| |
| /** @type {<This, A extends readonly unknown[]>(arr: A, iterator: (this: This | void, value: A[number], index: number, arr: A) => void, receiver: This | undefined) => void} */ |
| var forEachArray = function forEachArray(array, iterator, receiver) { |
| for (var i = 0, len = array.length; i < len; i++) { |
| if (hasOwnProperty.call(array, i)) { |
| if (receiver == null) { |
| iterator(array[i], i, array); |
| } else { |
| iterator.call(receiver, array[i], i, array); |
| } |
| } |
| } |
| }; |
| |
| /** @type {<This, S extends string>(string: S, iterator: (this: This | void, value: S[number], index: number, string: S) => void, receiver: This | undefined) => void} */ |
| var forEachString = function forEachString(string, iterator, receiver) { |
| for (var i = 0, len = string.length; i < len; i++) { |
| // no such thing as a sparse string. |
| if (receiver == null) { |
| iterator(string.charAt(i), i, string); |
| } else { |
| iterator.call(receiver, string.charAt(i), i, string); |
| } |
| } |
| }; |
| |
| /** @type {<This, O>(obj: O, iterator: (this: This | void, value: O[keyof O], index: keyof O, obj: O) => void, receiver: This | undefined) => void} */ |
| var forEachObject = function forEachObject(object, iterator, receiver) { |
| for (var k in object) { |
| if (hasOwnProperty.call(object, k)) { |
| if (receiver == null) { |
| iterator(object[k], k, object); |
| } else { |
| iterator.call(receiver, object[k], k, object); |
| } |
| } |
| } |
| }; |
| |
| /** @type {(x: unknown) => x is readonly unknown[]} */ |
| function isArray(x) { |
| return toStr.call(x) === '[object Array]'; |
| } |
| |
| /** @type {import('.')._internal} */ |
| module.exports = function forEach(list, iterator, thisArg) { |
| if (!isCallable(iterator)) { |
| throw new TypeError('iterator must be a function'); |
| } |
| |
| var receiver; |
| if (arguments.length >= 3) { |
| receiver = thisArg; |
| } |
| |
| if (isArray(list)) { |
| forEachArray(list, iterator, receiver); |
| } else if (typeof list === 'string') { |
| forEachString(list, iterator, receiver); |
| } else { |
| forEachObject(list, iterator, receiver); |
| } |
| }; |