memoize.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. var MapCache = require('./_MapCache');
  2. /** Error message constants. */
  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 used as the map cache key. The `func`
  9. * is invoked with the `this` binding of the memoized function.
  10. *
  11. * **Note:** The cache is exposed as the `cache` property on the memoized
  12. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  13. * constructor with one whose instances implement the
  14. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  15. * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  16. *
  17. * @static
  18. * @memberOf _
  19. * @since 0.1.0
  20. * @category Function
  21. * @param {Function} func The function to have its output memoized.
  22. * @param {Function} [resolver] The function to resolve the cache key.
  23. * @returns {Function} Returns the new memoized function.
  24. * @example
  25. *
  26. * var object = { 'a': 1, 'b': 2 };
  27. * var other = { 'c': 3, 'd': 4 };
  28. *
  29. * var values = _.memoize(_.values);
  30. * values(object);
  31. * // => [1, 2]
  32. *
  33. * values(other);
  34. * // => [3, 4]
  35. *
  36. * object.a = 2;
  37. * values(object);
  38. * // => [1, 2]
  39. *
  40. * // Modify the result cache.
  41. * values.cache.set(object, ['a', 'b']);
  42. * values(object);
  43. * // => ['a', 'b']
  44. *
  45. * // Replace `_.memoize.Cache`.
  46. * _.memoize.Cache = WeakMap;
  47. */
  48. function memoize(func, resolver) {
  49. if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
  50. throw new TypeError(FUNC_ERROR_TEXT);
  51. }
  52. var memoized = function() {
  53. var args = arguments,
  54. key = resolver ? resolver.apply(this, args) : args[0],
  55. cache = memoized.cache;
  56. if (cache.has(key)) {
  57. return cache.get(key);
  58. }
  59. var result = func.apply(this, args);
  60. memoized.cache = cache.set(key, result) || cache;
  61. return result;
  62. };
  63. memoized.cache = new (memoize.Cache || MapCache);
  64. return memoized;
  65. }
  66. // Expose `MapCache`.
  67. memoize.Cache = MapCache;
  68. module.exports = memoize;