code: function memoize(func, resolver) {
        if (!isFunction(func)) {
          throw new TypeError;
        }
        var memoized = function() {
          var cache = memoized.cache,
              key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
  
          return hasOwnProperty.call(cache, key)
            ? cache[key]
            : (cache[key] = func.apply(this, arguments));
        }
        memoized.cache = {};
        return memoized;
      }
docs: Creates a function that memoizes the result of `func`. If `resolver` is
  provided it will be used to determine the cache key for storing the result
  based on the arguments provided to the memoized function. By default, the
  first argument provided to the memoized function is used as the cache key.
  The `func` is executed with the `this` binding of the memoized function.
  The result cache is exposed as the `cache` property on the memoized function.
  
  @static
  @memberOf _
  @category Functions
  @param {Function} func The function to have its output memoized.
  @param {Function} [resolver] A function used to resolve the cache key.
  @returns {Function} Returns the new memoizing function.
  @example
  
  var fibonacci = _.memoize(function(n) {
  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
  });
  
  fibonacci(9)
  // => 34
  
  var data = {
  'fred': { 'name': 'fred', 'age': 40 },
  'pebbles': { 'name': 'pebbles', 'age': 1 }
  };
  
  // modifying the result cache
  var get = _.memoize(function(name) { return data[name]; }, _.identity);
  get('pebbles');
  // => { 'name': 'pebbles', 'age': 1 }
  
  get.cache.pebbles.name = 'penelope';
  get('pebbles');
  // => { 'name': 'penelope', 'age': 1 }