探秘JavaScript:手写memoize函数全解析

memoize 函数主要作用:

memoize 函数主要的作用是缓存函数的计算结果。当一个函数被memoize包装后,它会记住之前传入相同参数时的返回值。

例如,假设有一个计算斐波那契数列的函数fibonacci。斐波那契数列的定义是:F(n)=F(n - 1)+F(n - 2),其中F(0)=0,F(1)=1

javascript 复制代码
function fibonacci(n) {
    if (n === 0) {
        return 0;
    }
    if (n === 1) {
        return 1;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

手写实现方法:

javascript 复制代码
class MemoizeMap {
  constructor() {
    this._map = new Map()
    this._weakMap = new WeakMap()
  }
  _isObject(value) {
    return typeof value === 'object' && value !== null
  }
  get(key) {
    if(this._isObject(key)) {
      return this._weakMap.get(key)
    }
    return this._map.get(key)
  }
  set(key, value) {
    if(this._isObject(key)) {
      this._weakMap.set(key, value)
    }
    this._map.set(key, value)
  }
  has(key) {
    if(this._isObject(key)) {
      return this._weakMap.has(key)
    }
    return this._map.has(key)
  }
}

/**
 * 缓存函数
 * @param {*} fn 方法函数
 * @param {*} resolver 存储的 key,可自定义
 * @returns 方法函数结果
 */
function memoize(fn, resolver) {
  if(typeof resolver !== 'function') {
    resolver = (key) => key
  }
  function memoized(...args) {
    const key = resolver(...args)
    if(memoized.cache.has(key)) {
      return memoized.cache.get(key)
    }
    console.log(key, 'key')
    const result = fn.apply(this, args)
    memoized.cache.set(key, result)
    return result
  }
  memoized.cache = new MemoizeMap()
  return memoized
}

const obj1 = {
  a: 1,
  b: 2
}
const other = {
  a: 3,
  b: 4
}

const fn = memoize((obj) => Object.values(obj))
console.log(fn(obj1));

console.log(fn(other));

obj1.b = 'lhc'
console.log(fn(obj1));

fn.cache.set(obj1, ['l', 'h', 'c'])
console.log(fn(obj1));
相关推荐
Joy T3 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
半个落月6 小时前
LangSmith 全链路观测(下):用 Dataset 与 LLM Judge 量化评估 RA
javascript·langchain
专注仿真6 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
Best-Wishes7 小时前
科来网络分析系统(技术交流版)使用说明书
开发语言·junit·php
半个落月7 小时前
LangSmith 全链路观测(上):用 LangGraph 与 Milvus 构建可追踪的 RAG 客服
javascript·langchain
代码不停7 小时前
自动化测试(java)
java·开发语言·selenium·自动化
半个落月7 小时前
LangChain.js Agent 中间件实战:生命周期、动态工具与文件权限
javascript·langchain
志尊宝9 小时前
Vue3 零基础每日笔记(082):文件上传实战——el-upload 校验、自定义上传、头像预览
前端·javascript·vue.js·笔记·#javascript·#vue.js
鬼手点金9 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
爱上网的小舟9 小时前
星际战士2启动错误怎么办?5种游戏报错解决方法
开发语言·php