JS如何实现装饰器?装饰器模式应用详解

来源:Java编程网作者:关中王头衔:草根站长
导读:本期聚焦于小伙伴创作的《JS如何实现装饰器?装饰器模式应用详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JS如何实现装饰器?装饰器模式应用详解》有用,将其分享出去将是对创作者最好的鼓励。

装饰器模式的核心思想是通过包装原有对象或函数,在不改变其原有逻辑的基础上扩展新功能,这种模式在JavaScript开发中应用十分广泛,能够有效避免修改原有代码带来的风险,同时让功能扩展更加灵活。

JS如何实现装饰器?装饰器模式应用详解

装饰器模式的核心概念

装饰器模式属于结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。在JS中,装饰器可以作用于函数、类、类的方法等,核心是通过一层包装层来拦截原有逻辑,在原有逻辑执行前后插入自定义操作。

装饰器模式的主要优势在于遵循开闭原则,即对扩展开放,对修改关闭,当需要新增功能时不需要修改原有代码,只需要新增装饰器即可,降低了代码的耦合度。

JS实现装饰器的常见方式

1. 函数包装实现装饰器

函数包装是最基础的装饰器实现方式,通过将原函数作为参数传入装饰器函数,在装饰器内部返回一个新的函数,新的函数会先执行扩展逻辑,再执行原函数逻辑,或者反过来。

下面是一个给函数添加执行时间统计功能的装饰器示例:

// 原函数:模拟一个耗时操作
function originalFunc() {
  console.log('执行原函数的核心逻辑');
  // 模拟耗时
  for (let i = 0; i < 1000000000; i++) {}
}

// 装饰器函数:统计函数执行时间
function timeDecorator(fn) {
  return function(...args) {
    const startTime = Date.now();
    console.log('函数开始执行');
    // 执行原函数,保留原函数的this指向和参数
    const result = fn.apply(this, args);
    const endTime = Date.now();
    console.log(`函数执行耗时:${endTime - startTime}ms`);
    return result;
  };
}

// 使用装饰器包装原函数
const decoratedFunc = timeDecorator(originalFunc);
// 执行装饰后的函数
decoratedFunc();

2. ES7标准装饰器语法

ES7引入了装饰器的语法提案,目前虽然还未正式成为标准,但可以通过Babel等工具进行转译使用。ES7装饰器可以直接作用于类、类的方法、类的属性,使用@装饰器名称的语法来使用。

下面是一个类方法装饰器的示例,实现方法调用前的权限校验功能:

// 定义权限校验装饰器
function authDecorator(target, propertyKey, descriptor) {
  const originalMethod = descriptor.value;
  // 修改方法的描述符,替换原有方法
  descriptor.value = function(...args) {
    // 模拟权限校验逻辑
    const hasAuth = true; // 实际场景中可以从用户信息中获取
    if (!hasAuth) {
      throw new Error('没有操作权限');
    }
    console.log('权限校验通过');
    // 执行原有方法
    return originalMethod.apply(this, args);
  };
  return descriptor;
}

class UserService {
  // 使用装饰器
  @authDecorator
  deleteUser(userId) {
    console.log(`删除用户:${userId}`);
    return true;
  }
}

const service = new UserService();
service.deleteUser(123);

装饰器模式的常见应用场景

日志记录

在方法执行前后自动记录日志,不需要在每个方法内部手动写日志代码,通过装饰器统一处理,减少重复代码。

性能统计

如前面示例所示,统计函数的执行时间、调用次数等性能指标,不需要侵入原有业务逻辑。

缓存处理

对于计算成本高的函数,可以通过装饰器添加缓存逻辑,当传入相同参数时直接返回缓存结果,避免重复计算。

下面是一个缓存装饰器的示例:

// 缓存装饰器
function cacheDecorator(fn) {
  const cache = new Map();
  return function(...args) {
    // 将参数转为字符串作为缓存键
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      console.log('命中缓存,直接返回结果');
      return cache.get(key);
    }
    // 没有缓存则执行原函数并缓存结果
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

// 模拟一个耗时的计算函数
function calculate(num) {
  console.log('执行计算逻辑');
  return num * 2;
}

const cachedCalculate = cacheDecorator(calculate);
console.log(cachedCalculate(5)); // 第一次执行,会走计算逻辑
console.log(cachedCalculate(5)); // 第二次执行,命中缓存

使用装饰器的注意事项

首先,装饰器的执行顺序需要注意,多个装饰器作用于同一个目标时,会从外到内进入,从内到外执行。其次,使用ES7装饰器时需要确认项目的转译配置,确保装饰器语法能够被正确解析。另外,装饰器虽然灵活,但也不要过度使用,过多的装饰器嵌套会增加代码的阅读难度,不利于后续维护。

装饰器模式是JS中非常实用的设计模式,掌握它的实现方式和应用场景,能够帮助我们写出更优雅、更易维护的代码,在需要动态扩展功能的时候优先考虑装饰器模式,可以有效降低代码的耦合度。

装饰器模式JS装饰器JavaScript设计模式函数装饰器修改时间:2026-06-19 16:03:43

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。