From 10f13c0904e497a35bb4cba907490aad1ba6d879 Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Tue, 14 May 2019 23:25:20 +0800 Subject: [PATCH] Cache function reference when it's a single argument (#35) Co-Authored-By: Sindre Sorhus --- index.d.ts | 2 +- index.js | 8 +++----- readme.md | 2 +- test.js | 14 ++++++++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index 7866255..86acff4 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,7 +20,7 @@ declare namespace mem { readonly maxAge?: number; /** - Determines the cache key for storing the result based on the function arguments. By default, if there's only one argument and it's a [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive), it's used directly as a key, otherwise it's all the function arguments JSON stringified as an array. + Determines the cache key for storing the result based on the function arguments. By default, if there's only one argument and it's a [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive), it's used directly as a key (if it's a `function`, its reference will be used as key), otherwise it's all the function arguments JSON stringified as an array. You could for example change it to only cache on the first argument `x => JSON.stringify(x)`. */ diff --git a/index.js b/index.js index 51faf01..5669a0a 100644 --- a/index.js +++ b/index.js @@ -12,11 +12,9 @@ const defaultCacheKey = (...arguments_) => { if (arguments_.length === 1) { const [firstArgument] = arguments_; - if ( - firstArgument === null || - firstArgument === undefined || - (typeof firstArgument !== 'function' && typeof firstArgument !== 'object') - ) { + const isObject = typeof firstArgument === 'object' && firstArgument !== null; + const isPrimitive = !isObject; + if (isPrimitive) { return firstArgument; } } diff --git a/readme.md b/readme.md index add4222..65f10bf 100644 --- a/readme.md +++ b/readme.md @@ -101,7 +101,7 @@ Milliseconds until the cache expires. Type: `Function` -Determines the cache key for storing the result based on the function arguments. By default, if there's only one argument and it's a [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive), it's used directly as a key, otherwise it's all the function arguments JSON stringified as an array. +Determines the cache key for storing the result based on the function arguments. By default, if there's only one argument and it's a [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive), it's used directly as a key (if it's a `function`, its reference will be used as key), otherwise it's all the function arguments JSON stringified as an array. You could for example change it to only cache on the first argument `x => JSON.stringify(x)`. diff --git a/test.js b/test.js index f48e4b7..d1b692c 100644 --- a/test.js +++ b/test.js @@ -15,6 +15,20 @@ test('memoize', t => { t.is(memoized('foo', 'bar'), 2); t.is(memoized('foo', 'bar'), 2); t.is(memoized('foo', 'bar'), 2); + t.is(memoized(1), 3); + t.is(memoized(1), 3); + t.is(memoized(null), 4); + t.is(memoized(null), 4); + t.is(memoized(undefined), 5); + t.is(memoized(undefined), 5); + t.is(memoized(fixture), 6); + t.is(memoized(fixture), 6); + t.is(memoized(true), 7); + t.is(memoized(true), 7); + + // Ensure that functions are stored by reference and not by "value" (e.g. their `.toString()` representation) + t.is(memoized(() => i++), 8); + t.is(memoized(() => i++), 9); }); test('memoize with multiple non-primitive arguments', t => {