前端小技巧: 面向切面编程在前端代码中的应用

扩展方法不是语法糖:一种可迁移的编程思维范式 扩展方法表面是C#中为类型添加便捷行为的语法特性,实则承载着关注点分离、契约优先、组合演化与防御性设计等核心编程原理。它本质是一种在不修改原始结构前提下安全增强能力的通用范式,广泛适用于领域建模、微服务客户端封装、事件处理器注册及云原生资源操作等场景。其技术价值在于将横切逻辑解耦为可测试、可组合、可演进的轻量级能力单元,推动开发者从‘如何写代码’转向‘谁该拥有这个责任’的深层思考。本文基于真实重构案例,解析扩展方法背后隐藏的四大工程思维,帮助中级开发者突破职责模糊、语义缺失与协作失序等典型困境。 阅读详情

面向切面编程

  • 面向切面编程在java中提出这类概念
  • 但是在js没有束缚和约定,只需要按编程思想来实现原理
  • 在js中使用function或class实现面向切面编程

面向切面概念

  • AOP (Aspect Oriented Programming) 面向切面编程
  • 主要实现目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或者阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果
  • 类比
    • 用刀切西瓜,西瓜红壤面就是切面,可以两驱切面的圆周和面积
    • 无侵入式的干扰
    • 只需要两篇,比如开头和结尾截取, 而非随意切,横切,竖切
    • 处理业务某个中间的部分,提取和隔离,不对具体业务干扰
    • 比如在业务中穿插了一些代码,比如网页性能检测,用js埋点
    • 不在里面埋点,在整体业务上加东西,在函数之前或之后执行,如果哪天有热插拔的需求,把函数抽走,也不影响原来的业务
    • 埋点函数和原来业务不会影响和混淆

代码实现

  • 比如, 统计当前所有函数谁耗时最长,最性能优化

  • 1 )侵入式演示: 每个函数前后加代码

    function test() {
      console.time()
      alert(2)
      console.timeEnd()
    }
    
  • 2 ) 在原型链上添加函数优化,先忽略这个 console.time/timeEnd 统计函数

    • 2.1 只添加before函数到原型链上

      function test() {
        alert(2)
      }
      
      Function.prototype.before = function (fn) {
        fn() // 执行前置任务
        this.apply(this, arguments) // 执行自身
      }
      // 演示
      test.before(function() {
        alert(1)
      })
      
    • 2.2 只添加after函数到原型链上

      function test() {
        alert(2)
      }
      
      Function.prototype.after = function (fn) {
        // 先执行 this本身,再执行回调
        this.apply(this, arguments) // 执行自身
        fn() // 执行前置任务
      }
      
      // 演示
      test.after(function() {
        alert(3)
      })
      
    • 2.3 将before和after函数添加到原型链上

      function test() {
        alert(2)
      }
      
      Function.prototype.before = function (fn) {
        fn() // 执行前置任务
        // return this.apply(this, arguments) // 执行自身 // 这里可以return 用于其他
        this.apply(this, arguments) // 执行自身
      }
      
      Function.prototype.after = function (fn) {
        // 先执行 this本身,再执行回调
        this.apply(this, arguments)
        fn() // 执行后置任务
      }
      
      // 演示
      test.before(function() {
        alert(1)
      })
      test.after(function() {
        alert(3)
      })
      
      • 这时候默认函数被执行了2遍,需要优化
  • 5 ) 继续优化重复执行的默认函数,将this只在before中执行

    function test() {
      alert(2)
    }
    
    Function.prototype.before = function (fn) {
      fn() // 执行前置任务
      // return this.apply(this, arguments) // 执行自身 // 这里可以return 用于其他
      this.apply(this, arguments) // 执行自身
    }
    
    Function.prototype.after = function (fn) {
      // 先执行 this本身,再执行回调
      // this.apply(this, arguments) // 执行自身
      fn() // 执行后置任务
    }
    
    // 演示
    test.before(function() {
      alert(1)
    })
    test.after(function() {
      alert(3)
    })
    
    • 以上是原型链中添加, 这完全没问题,但是写了两次
  • 6 ) 支持链式调用版本优化

    function test() {
      alert(2)
    }
    
    Function.prototype.before = function (fn) {
      var _self = this
      return function () {
        fn.apply(this, arguments)
        _self.apply(this, arguments)
      }
    }
    
    Function.prototype.after = function (fn) {
      var _self = this
      return function () {
        _self.apply(this, arguments)
        fn.apply(this, arguments)
      }
    }
    
    • 基于以上代码,如果这样测试, 测试1:
      // 演示
      test.before(function() {
        alert(1)
      }).after(function() {
        alert(3)
      })()
      
      • 它的输出顺序是
        after
        before
        1
        2
        before over
        3
        after over
        
    • 如果这样测试, 测试2
       test.after(() => {
          alert(3)
        }).before(() => {
          alert(1)
        })()
      
      • 它的输出顺序是
        before
        1
        after
        2
        3
        after over
        before over
        
  • 注意的是 this 指针的引用,使用function而非箭头函数
  • 以上示例,不管先调用before还是after
    • 都会先执行before中的fn
    • 之后是默认函数
    • 最后才是after的fn
    • 输出顺序都是: 1 2 3

7 ) 链式调用,并支持异常断开

function test() {
  alert(2)
  // return false // 注意这里可以打开,尝试
  return 'test'
}

Function.prototype.before = function (fn) {
  var _self = this
  return function () {
    // 下面的 if 写法比较麻烦,但这样写算比较清晰吧
    if (fn.apply(this, arguments) === false) {
      return false
    }
    return _self.apply(this, arguments)
  }
}

Function.prototype.after = function (fn) {
  var _self = this
  return function () {
    var result = _self.apply(this, arguments)
    if (result === false) return false
    fn.apply(this, arguments)
    return result // 这里注意
  }
}

// 演示
test.before(function() {
  alert(1)
}).after(function() {
  alert(3)
})()
  • 注意以上 === 判断中,关于 false 和 undefined区别
  • undefined 意味着成功,只有主动 false 时,才可以
  • 还可以换一种写法,比如 return true时,继续,其他都拒绝执行
  • 每一层都可以 return , 可return成任意值,只有false才会阻断
SSM框架实战:图书馆管理系统课设全流程解析与核心代码实现 在Java Web开发领域,SSM(Spring+Spring MVC+MyBatis)框架组合是构建企业级应用的主流技术选型,其核心在于通过分层架构实现高内聚、低耦合的系统设计。Spring框架的IoC(控制反转)和AOP(面向切面编程)原理,实现了对象生命周期的自动化管理和横切关注点的统一处理,例如声明式事务管理,这为复杂业务逻辑提供了坚实的支撑。Spring MVC作为Web层的控制器,清晰地处理HTTP请求分发与响应,而MyBatis作为半自动化的ORM框架,通过动态SQL和手写SQL映射,赋予开发 阅读详情

相关推荐

Spring Boot+Vue前后端分离开发实战:从环境搭建到部署上线

前后端分离架构是现代Web开发的主流模式,其核心在于将数据接口与页面展示解耦,后端通过RESTful API提供JSON数据,前端采用Vue等框架进行响应式渲染。Spring Boot凭借成熟的生态和企业级稳定性,成为实现后端服务的常用选择;Vue则以其友好的学习曲线和灵活的组合式API,显著提升了前端开发效率。两者结合时,跨域处理、JWT身份认证、统一接口规范等工程实践尤为关键。掌握这些技术要点,不仅能快速构建高复用、易维护的业务系统,还能为后续Docker容器化部署和自动化运维打下坚实基础。本文基于一个

weixin_34320724的博客 445

JavaScript 面向切面编程(AOP,装饰者模式)

需要注意的是,上述示例代码仅是为了说明 AOP 的基本思想和实现方式,实际应用中需要根据具体场景进行完善和修改。需要注意的是,上述示例代码仅是为了说明 AOP的基本思想和实现方式,实际应用中需要根据具体场景进行完善和修改。执行上面的代码后,会先在控制台输出 "Start log:",再输出 "Hello John",最后输出 "End log:"。执行上面的代码后,会先在控制台输出 "Start log:",再输出 "Hello John",最后输出 "End log:"。

风清扬的专栏 712

JS中的面向切片编程(AOP)

在上面的代码中,withLogging是一个高阶函数(Higher Order Function),它返回的函数可以包装一个函数,并能够记录该函数的输入和输出。add是一个需要包装的函数,它的功能是相加两个数。用withLogging包装add得到的loggedAdd函数,可以在add函数执行前输出"entering add",在add函数执行后输出"exiting add",并返回add函数的执行结果。方法的描述符,用一个新的函数来替代原有的方法,并在新的函数中添加了日志记录的功能。

廖龙东个人博客 506

SpringBoot使用mybatis-plus的自动代码生成器

一.SpringBoot使用mybatis-plus+自动代码生成 使用mybatis-plus可以自动帮我们生成通用的 controller,service,dao,mapper 二.加入依赖 <!-- MP 核心库 --> <dependency> <groupId>com.baomidou</groupId> <artif...

农民娃儿的博客 2267

Icarus Verilog和GTKwave使用简析

本简要介绍Icarus Verilog和GTKwave的使用,使用iverilog(Icarus Verilog)编译仿真verilog而使用GTKWave查看仿真数据波形下载安装 基本使用 iverilog使用 GTKWave使用 iverilog常用选项 使用库 注意

husipeng86的专栏 1万+

JS面向切面(AOP)

今天看了看切面,不是太懂 但是突发奇想,应该能使用ES6的proxy来写一个控制在函数Before和after执行其他内容的小玩具 class aop { constructor(obj, beforeFork, afterFork) { return new Proxy(obj, { get: function (target, propKey, receiver) { for (let

启明星的指引---博客 1055

Day2 十分钟带你解决逆向中对称加密算法 (RC4)

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种串流加密算法,密钥长度可变。他加密解密使用相同的密钥,因此也被称为“流加密算法”。RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。由于异或运算的对合性,RC4加密解密使用同一套算法。

m0_73779708的博客 1289

深入浅出JavaScript AOP:面向切面编程实践指南

AOP(面向切面编程)是一种编程范式,旨在将横切关注点(如日志记录、性能监测、事务管理等)与核心业务逻辑分离,提高代码的可维护性和复用性。AOP 允许我们在不修改核心业务逻辑的情况下,动态织入额外的功能。AOP 允许我们在不修改核心业务代码的前提下,动态织入横切关注点(如日志、监控、权限校验等),从而提升代码的解耦性、可扩展性和可维护性。在 JavaScript 中,我们可以通过扩展 Function.prototypebefore():在方法执行前插入逻辑after():在方法执行后插入逻辑。

qq_66118130的博客 1090

SAP-ABAP:SAP数据库视图的创建图文详解

在“短文本”字段中输入视图的描述。在“表/视图”字段中输入要基于的表名。如果视图基于多个表,可以在这里输入主表。点击“表/视图字段”按钮,选择要包含在视图中的字段。如果视图基于多个表,点击“关系”按钮来定义表之间的连接条件。在弹出的窗口中,选择要连接的表,并定义连接条件(例如。

baidu_35680696的博客 974

南京理工大学计算机预推免面试(双非重点关注)

南京理工大学总体来说对双非学校比较友好,上岸率比较高,而且面试形式是线上,在预推免的过程中,可以作为重点关注的学校,但是一定要注意南理报名截止的时间,部分学校可能保研名额公示的比较晚,对于保研边缘人来说很可能会错过,我的建议是,即使不确定能否拿到保研名额,先查一下截止时间,先在系统上报名!!一旦拿到了offer,就是铁的,保底专硕,而且有很大的技巧性,一定要认真看哈!!!每个人的情况可能都不一样,如果有需要帮忙可以私我~~~

D1379951481的博客 2020

前端解读面向切面编程(AOP)

前言 面向对象(OOP)作为经典的设计范式,对于我们来说可谓无人不知,还记得我们入行起始时那句经典的总结吗-万事万物皆对象。 是的,基于OOP思想封装、继承、多态的特点,我们会自然而然的遵循模块化、组件化的思维来设计开发应用,以到达易维护、可扩展、高复用的目的。 既然OOP这么多优点,那么经常被大家提起的面向切面编程(AOP)是什么回事呢,下面我们就一起来看一下。 AOP定义 第一步还是要知道ao...

weixin_33804582的博客 325

组基轨迹建模 GBTM的介绍与实现(Stata 或 R)

组基轨迹建模(Group-Based Trajectory Modeling,GBTM)(旧名称:Semiparametric mixture model)历史:由DANIELS.NAGIN提出,发表文献《Analyzing Developmental Trajectories:A Semiparametric,Group-Based Approach》GBTM能够将一群人的轨迹分类并生成数个具有代表性的运动轨迹模型,然后对每个轨迹模型进行分析,以了解人们的运动特征、生理水平和风险等级等。

三分钟热度 1万+

前端油猴脚本开发小技巧笔记

jquery 选择器,加空格是匹配下一级,紧密排列是且,[a=b]匹配属性。jquery 对象 a,a[0]是对应的原生dom对象,$(原生对象) 得到对应的 jquery 对象。查找某个按钮绑定事件是哪个函数,可以某个执行位置打断点,然后向上查找调用栈,再利用5查找。控制台直接输入函数名,可以打印出该函数的代码,继续点击代码可以跳转到对应的代码位置。vue代码method里的方法位置是vue对象的根目录,data里的变量也是。调试模式下,单击选中某dom代码,控制台里可以用$0访问到该dom对象。

buyulian的博客 1306

uniapp(全端兼容) - 最新详细实现支付键盘功能组件,从底部弹出数字键盘输入支付密码进行付款交互效果,自定义支付密码键盘仿微信、支付宝支付键盘,1~9密码数字键盘,电商支付(详细示例代码复制运行

uniapp,微信小程序,自定义数字键盘,输入支付密码的键盘组件,uniapp小程序如何实现从底部弹出输入支付密码自定义键盘功能,uniapp小程序密码支付键盘组件插件,自定义数字键盘输入页面,怎么封装底部弹窗自定义数字键盘用于输入支付密码,uniapp小程序仿类似电商支付密码输入模态框,uniapp微信小程序平台实现自定义支付密码键盘,uniapp 密码支付,数字键盘,安全键盘,交易键盘,交易密码,交易密码输入框,uniapp自定义支付键盘: uniapp自定义支付键盘,uniapp小程序端实现键盘输入支

✅ 精选推荐文章 2907

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java小技巧:centos卸载nginx

一、Spring面试题 1、Spring 在ssm中起什么作用? 答: Spring:Spring轻量级框架。 作用:Bean工厂,用来管理Bean的生命周期和框架集成。 Spring框架的两大核心: ①. IOC/DI(控制反转/依赖注入) :把dao依赖注入到service层,service层反转给action层,Spring顶层容器为BeanFactory。 ②. AOP:面向切面编程。 2、Spring的事务? 答: 编程式事务管理:编程方式管理事务,极大灵活性,难维护。 声明式事务管理:可以将业务

m0_56830725的博客 583

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spring Boot 自定义注解实战:用常见的5个高频案例带你飞!

自定义注解是一种强大的元编程工具,允许在不修改原有代码逻辑的情况下,为程序添加额外的功能。通过AOP(面向切面编程)与自定义注解的结合,我们可以实现关注点分离,让业务代码更加清晰简洁

Micro麦可乐的博客 5583

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

基于Java+SSM+Flask萌宠物知识网站(源码+LW+调试文档+讲解等)/萌宠护理/宠物知识百科/养宠小技巧/萌宠健康指南/宠物饮食建议/宠物日常护理/宠物训练技巧/宠物疾病预防/宠物行为解读

前端:Flask、Python Web框架,后端语言Python后端:Spring+SpringMVC+Mybatis数据库:MySQL、SQLServer开发工具:IDEA、Eclipse、Navicat等✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!!Flask 在程序设计中以其简洁灵活而备受青睐。它是一个轻量级的 Web 应用框架,让程序设计者能够快速搭建起小型到中型规模的 Web 项目。其核心简洁明了,没有过多的复杂配置,使得开发者可以专注于业务逻辑的实现,极大地提高了开发效率。

擅长Java、Python、小程序、Web网站开发和计算机毕设项目实战✌ 57

thinkphp 助手函数url不生成https_RESTful API的ThinkPHP构建

技术只是工具,一定要结合想法来选择技术(技术只是实现我们的想法)抽象方法面对一个项目【先有想法,再去寻找工具,技术选型】1.服务端:ThinkPHP 5[1] +MySQL 构建REST API2.客户端:微信小程序,向服务端请求数据,完成自身行为逻辑3.CMS管理,数据的增删改查,在api中看做一个特殊的客户端以上就是三端分离:客户端,服务器,数据管理分离核心规则基于REST API规则,基于T...

weixin_39710462的博客 88

基于Java+SSM+HTML5萌宠物知识网站(源码+LW+调试文档+讲解等)/萌宠护理/宠物知识百科/养宠小技巧/萌宠健康指南/宠物饮食建议/宠物日常护理/宠物训练技巧/宠物疾病预防/宠物行为解读

前端:HTML5、BootStrap、CSS3、JavaScript、jQuery、LayUI后端:Spring、SpringMVC、Mybatis,这三个技术简称SSM,Maven构建项目jar包,Tomcat运行Web环境,后端语言Java数据库:MySQL、SQLServer开发工具:IDEA、Eclipse、Navicat等✌关于毕设项目技术实现问题讲解也可以给我留言咨询!!!HTML、CSS 和 JavaScript 在程序设计中共同奏响了美妙的乐章。

擅长Java、Python、小程序、Web网站开发和计算机毕设项目实战✌ 477

开篇:从零设计 Spring 框架——模块划分与核心思路

摘要: Spring框架通过模块化设计简化Java企业级开发,核心解决对象管理复杂、横切关注点分散等问题。采用控制反转(IoC)管理对象生命周期,依赖注入(DI)降低耦合,AOP分离日志/事务等通用逻辑。模块化架构包含核心容器(IoC)、AOP、数据访问(JDBC/ORM)、Web(MVC)、上下文(配置管理)和测试模块,每层专注特定功能。关键技术包括动态代理(JDK/CGLIB)、声明式事务(AOP)、DispatcherServlet请求分发等,最终实现高内聚、低耦合的企业应用开发范式。

chanalbert 1078

Java开发黄金三角:JUnit测试、自定义注解与枚举的实战应用

在Java开发中,单元测试、注解和枚举是提升代码质量与可维护性的核心基础技术。单元测试通过JUnit框架验证代码逻辑的正确性,是保障软件质量的关键环节;注解作为一种元数据机制,能以声明式方式为代码注入语义,实现关注点分离;枚举则提供了类型安全的常量定义,有效替代易出错的魔法字符串。这三者结合形成的工程化实践,能系统性地解决代码逻辑散乱、校验重复和可读性差等痛点,其技术价值在于构建出高内聚、低耦合且易于测试的健壮系统。典型的应用场景包括状态机校验、业务规则引擎和统一配置管理等。本文将以订单状态流转校验器为例,

weixin_30908103的博客 345

SpringBoot前后端分离后台管理系统分析,真香

Spring Security 提供了Spring EL表达式,允许我们在定义接口的方法上面添加注解来实现权限控制。比如下面的接口表示用户拥有 admin、menu:edit 权限中的任意一个就能能访问update接口。但是,由于每个接口都需要给超级管理员放行,所以单纯使用这种注解的方式每次都需要重复的添加 admin 权限、因此我们可以加入自定义权限验证方式,在验证的时候默认给拥有 admin 权限的用户放行。// 获取当前用户的所有权限// 判断当前用户的所有权限是否包含接口上定义的权限。

jjc4261的博客 744

JavaEE-核心知识

本文梳理了JavaEE核心技术知识体系,涵盖前端基础、服务器技术、数据库、JDBC、反射注解等核心内容。重点包括: 前端基础:HTML/CSS/JS三件套+jQuery,以及Ajax异步请求实现方式 服务器技术:B/S与C/S架构比较、Tomcat部署方式、HTTP协议特点 数据库技术:SQL分类、常用数据类型、表约束、多表查询(内/外连接、子查询) JDBC:标准六步操作流程,PreparedStatement防止SQL注入 反射机制:运行时动态获取类信息的能力,是框架底层实现的核心 全文以表格形式组织关

m0_61980960的博客 313

深入理解JavaScript设计模式之闭包与高阶函数

2023年的某一天,一场让我印象深刻的面试:面试官: “你了解闭包吗?请说一下你对闭包的理解。”我自信满满地答道: “闭包就是函数里面套函数,里面的函数可以访问外部函数的变量。” 面试官点点头,继续问:“那你知道高阶函数吗?”我依旧不慌不忙: “高阶函数嘛,就是能接收函数作为参数,或者返回一个函数的函数,在函数里执行回调的那种。”当时我心里还美滋滋地想:这不都是我看过的八股文嘛,稳了!走出面试室,我仿佛已经收到了 offer,决定先去吃顿大餐犒劳自己。吃完饭回到家,手机一响,是面试来电。电话那头传来...

前端开发工程师 1170
上一篇: 前端小技巧: 设计一个简版前端统计 SDK
下一篇: 前端小技巧: TS实现一个获取传入参数类型的函数
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值