新闻中心

装饰器模式:在JS中的实现与应用场景

2025-11-27
浏览次数:
返回列表
装饰器模式通过包装对象动态扩展功能,保持接口一致。1. 使用高阶函数实现日志、性能监控;2. ES装饰器语法支持类和方法增强,如只读、权限控制;3. 手动包装对象方法实现缓存、第三方库扩展。符合开闭原则,可组合多个装饰器,但需注意性能与执行顺序,ES装饰器语法仍处提案阶段。

装饰器模式:在js中的实现与应用场景

装饰器模式是一种结构型设计模式,它允许在不修改对象原有功能的基础上,动态地给对象添加新的行为或职责。这种模式通过“包装”对象的方式来扩展其功能,既保持了原有的接口一致性,又实现了灵活的扩展能力。在 J*aScript 中,装饰器模式可以通过函数、高阶函数、ES 装饰器语法(处于提案阶段)等多种方式实现。

J*aScript 中的实现方式

1. 函数装饰器(高阶函数)

最常见的实现方式是使用高阶函数对原函数进行包装:

function logDecorator(fn) {
  return function(...args) {
    console.log(`调用函数 ${fn.name},参数:`, args);
    const result = fn.apply(this, args);
    console.log(`函数 ${fn.name} 执行完成,返回值:`, result);
    return result;
  };
}

function add(a, b) {
  return a + b;
}

const loggedAdd = logDecorator(add);
loggedAdd(2, 3); // 输出日志并返回 5

2. 类与方法装饰器(使用 ES 装饰器语法)

虽然 ES 装饰器尚未正式纳入标准,但在 TypeScript 或 Babel 环境中已被广泛支持:

function readonly(target, name, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

class Calculator {
  @readonly
  add(a, b) {
    return a + b;
  }
}

上面的 @readonly 装饰器阻止了方法被重写,体现了装饰器对行为的控制。

3. 对象属性装饰(手动包装)

也可以直接包装对象的方法:

function timeDecorator(fn) {
  return function(...args) {
    console.time(fn.name);
    const result = fn.apply(this, args);
    console.timeEnd(fn.name);
    return result;
  };
}

const api = {
  fetchData() {
    return new Promise(resolve => {
      setTimeout(() => resolve("数据加载完成"), 1000);
    });
  }
};

api.fetchData = timeDecorator(api.fetchData);

常见应用场景

1. 日志记录与调试

在不侵入业务逻辑的前提下,为关键函数添加日志输出,便于追踪执行流程和排查问题。

2. 性能监控

多个微信小程序源码合集 多个微信小程序源码合集

微信小程序是一种轻量级的应用开发平台,由腾讯公司推出,主要应用于移动端,旨在提供便捷的用户体验,无需下载安装即可在微信内使用。本压缩包包含了丰富的源码资源,涵盖了多个领域的应用场景,下面将逐一介绍其中涉及的知识点。1. 图片展示:这部分源码可能涉及了微信小程序中的``组件的使用,用于显示图片,以及`wx.getSystemInfo`接口获取屏幕尺寸,实现图片的适配和响应式布局。可能还包括了图片懒加

多个微信小程序源码合集 0 查看详情 多个微信小程序源码合集

通过装饰器测量函数执行时间,适用于 API 请求、计算密集型操作等场景。

3. 权限控制与校验

在方法执行前检查用户权限或参数合法性:

function requireAuth(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function(...args) {
    if (!this.isAuthenticated) {
      throw new Error("未授权访问");
    }
    return original.apply(this, args);
  };
  return descriptor;
}

4. 缓存增强(Memoization)

为耗时函数添加缓存机制,避免重复计算:

function memoize(fn) {
  const cache = new Map();
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

5. 第三方库扩展

当无法修改第三方对象源码时,可用装饰器模式安全地扩展其功能,比如增强 Vue 或 React 组件的行为。

优势与注意事项

优点:

  • 符合开闭原则:对扩展开放,对修改封闭
  • 功能解耦,职责清晰
  • 可组合多个装饰器,实现链式增强

注意点:

  • 避免过度装饰导致性能下降或逻辑复杂
  • 装饰器顺序可能影响结果,需明确执行顺序
  • ES 装饰器语法仍在演进,生产环境需评估兼容性
基本上就这些。装饰器模式在 J*aScript 中虽无原生完整支持,但凭借其灵活的函数式特性,依然能优雅实现,特别适合需要动态增强行为的场景。

以上就是装饰器模式:在JS中的实现与应用场景的详细内容,更多请关注其它相关文章!


# 复用  # 长沙哪网站建设好  # 网站设计建置优化之道 pdf  # 淘宝有SEO优化吗  # 互联网网站优化成功案例  # 连衣裙关键词排名  # 北京公交网站建设  # 营销软文如何推广  # 丁镇网站建设  # 网站推广营销收费标准  # 营销推广哪家比较专业的  # 已被  # 基础上  # 开闭  # vue  # 链式  # 是一种  # 第三方  # 高阶  # 合集  # 多个  # app  # typescript  # json  # js  # java  # javascript  # react 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 零跑汽车11月交付量达70327台 实现连续9个月正增长  C++ typeid如何获取类型信息_C++ RTTI运行时类型识别用法  2026年发布! 美少女养成动作RPG《神剑少女战记》发布实机演示  PDF怎么合并PDF并保持格式_PDF合并文件保持排版教程  《GTA6》开发画面疑似泄露!这次可不是AI了  126邮箱网页版官方入口 126邮箱账号在线登录平台  J*aScript打印功能_j*ascript输出控制  163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航  深入理解J*aScript Promise异步执行与微任务队列  AO3官方在线访问地址 Archive of Our Own最新镜像合集  凉拌黄瓜怎么拌更入味 凉拌黄瓜简单家常做法  蛙漫2台版漫画地址 Manwa2正版网页版链接  神庙逃亡小游戏在线玩 神庙逃亡小游戏入口  12306几点到几点不能订票? | 官方最新系统维护时间全解析  Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题  Mudbox图层蒙版怎么用_Mudbox图层蒙版数字雕刻应用技巧  J*aScript数组对象转换:按指定键分组与值收集  解决Python logging 中 datefmt 导致时间戳固定不变的问题  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  Archive of Our Own官网直达 AO3最新可用地址一览  CKEditor 5 自定义构建在React应用中渲染失败的调试与解决  在J*a中如何开发简易仓库管理与库存统计_仓库管理库存统计项目实战解析  Surface怎么安装系统 微软Surface Pro U盘重装win11教程  outlook中文官网入口地址 outlook官方中文版直达首页链接  mc.js免安装版 mc.js一键畅玩入口  12306选座怎么选到商务座_12306商务座选择与配置说明  CSS Box Model与弹性按钮:维持布局稳定的动画实践  探索高级语言到原生C/C++的转译:挑战与内存管理策略  Yandex官网免登录入口_俄罗斯Yandex搜索引擎一键访问  怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】  Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践  React/Next.js中实现列表项的动态选择与移动  在Pyomo中实现基于变量的条件约束:Big-M方法详解  痛风发作了怎么办? 快速止痛和后期饮食调理  CSS响应式网页如何实现主次模块比例自适应_flex-grow与flex-shrink调整  sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置  ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接  腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程  怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法  Python多线程中正确使用sigwait处理SIGALRM信号  ExcelARRAYTOTEXT函数怎么自定义分隔符输出数组文本_ARRAYTOTEXT实现动态生成SQL语句  天猫双十一预售商品怎么退款_天猫双十一预售退款操作指南  如何设置Windows Defender的定时扫描_计划任务实现自动杀毒【安全】  大象笔记网页版入口 印象笔记网页版登录入口  优化Log4j2控制台输出性能:解决异步日志瓶颈  Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性  使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  J*aScript中高效管理与清空动态列表:避免循环陷阱  css滚动区域卡顿如何改善_css滚动问题用will-change优化渲染 

搜索