text: 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)
          }
      }
  }
  