--- /dev/null
+var isFunction = require('is-function')
+
+module.exports = forEach
+
+var toString = Object.prototype.toString
+var hasOwnProperty = Object.prototype.hasOwnProperty
+
+function forEach(list, iterator, context) {
+ if (!isFunction(iterator)) {
+ throw new TypeError('iterator must be a function')
+ }
+
+ if (arguments.length < 3) {
+ context = this
+ }
+
+ if (toString.call(list) === '[object Array]')
+ forEachArray(list, iterator, context)
+ else if (typeof list === 'string')
+ forEachString(list, iterator, context)
+ else
+ forEachObject(list, iterator, context)
+}
+
+function forEachArray(array, iterator, context) {
+ for (var i = 0, len = array.length; i < len; i++) {
+ if (hasOwnProperty.call(array, i)) {
+ iterator.call(context, array[i], i, array)
+ }
+ }
+}
+
+function forEachString(string, iterator, context) {
+ for (var i = 0, len = string.length; i < len; i++) {
+ // no such thing as a sparse string.
+ iterator.call(context, string.charAt(i), i, string)
+ }
+}
+
+function forEachObject(object, iterator, context) {
+ for (var k in object) {
+ if (hasOwnProperty.call(object, k)) {
+ iterator.call(context, object[k], k, object)
+ }
+ }
+}