memoize.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. var MapCache = require('../internal/MapCache');
  2. /** Used as the `TypeError` message for "Functions" methods. */
  3. var FUNC_ERROR_TEXT = 'Expected a function';
  4. /**
  5. * Creates a function that memoizes the result of `func`. If `resolver` is
  6. * provided it determines the cache key for storing the result based on the
  7. * arguments provided to the memoized function. By default, the first argument
  8. * provided to the memoized function is coerced to a string and used as the
  9. * cache key. The `func` is invoked with the `this` binding of the memoized
  10. * function.
  11. *
  12. * **Note:** The cache is exposed as the `cache` property on the memoized
  13. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  14. * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
  15. * method interface of `get`, `has`, and `set`.
  16. *
  17. * @static
  18. * @memberOf _
  19. * @category Function
  20. * @param {Function} func The function to have its output memoized.
  21. * @param {Function} [resolver] The function to resolve the cache key.
  22. * @returns {Function} Returns the new memoizing function.
  23. * @example
  24. *
  25. * var upperCase = _.memoize(function(string) {
  26. * return string.toUpperCase();
  27. * });
  28. *
  29. * upperCase('fred');
  30. * // => 'FRED'
  31. *
  32. * // modifying the result cache
  33. * upperCase.cache.set('fred', 'BARNEY');
  34. * upperCase('fred');
  35. * // => 'BARNEY'
  36. *
  37. * // replacing `_.memoize.Cache`
  38. * var object = { 'user': 'fred' };
  39. * var other = { 'user': 'barney' };
  40. * var identity = _.memoize(_.identity);
  41. *
  42. * identity(object);
  43. * // => { 'user': 'fred' }
  44. * identity(other);
  45. * // => { 'user': 'fred' }
  46. *
  47. * _.memoize.Cache = WeakMap;
  48. * var identity = _.memoize(_.identity);
  49. *
  50. * identity(object);
  51. * // => { 'user': 'fred' }
  52. * identity(other);
  53. * // => { 'user': 'barney' }
  54. */
  55. function memoize(func, resolver) {
  56. if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
  57. throw new TypeError(FUNC_ERROR_TEXT);
  58. }
  59. var memoized = function() {
  60. var args = arguments,
  61. key = resolver ? resolver.apply(this, args) : args[0],
  62. cache = memoized.cache;
  63. if (cache.has(key)) {
  64. return cache.get(key);
  65. }
  66. var result = func.apply(this, args);
  67. memoized.cache = cache.set(key, result);
  68. return result;
  69. };
  70. memoized.cache = new memoize.Cache;
  71. return memoized;
  72. }
  73. // Assign cache to `_.memoize`.
  74. memoize.Cache = MapCache;
  75. module.exports = memoize;