You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.3 KiB
69 lines
2.3 KiB
'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); |
|
} |
|
};
|
|
|