Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Thinking--AOP思想在前端中的应用

Thinking--AOP思想在前端中的应用

作者头像
奋飛
发布于 2019-08-14 10:00:58
发布于 2019-08-14 10:00:58
41600
代码可运行
举报
文章被收录于专栏:Super 前端Super 前端
运行总次数:0
代码可运行

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。

AOP

AOP(Aspect Oriented Programming),面向切面编程。其从主关注点中分离出横切关注点是面向侧面的程序设计的核心概念。分离关注点使得解决特定领域问题的代码从业务逻辑中独立出来。

具体到 Javascript 来说,由于语言本身的特性,天生就具有运行时动态插入逻辑的能力。重点在于在原函数上增加其他功能并不改变函数本身。

Spring中的Advice:前置通知(Before Advice)、后置通知(After Advice)、返回通知(After Return Advice)、环绕通知(Around Advice)、抛出异常后通知(After Throwing Advice)

javascript实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Function.prototype.after = function (action) {
    // 保留当前函数,这里this指向运行函数
    var func = this
    // return 被包装过的函数,这里就可以执行其他功能了
    // 并且该方法挂在 Function.prototype 上,
    // 被返回的函数依然具有 after 属性,可以链式调用
    return function () {
        // 原函数执行,这里不考虑异步
        var result = func.apply(this, arguments)
        // 执行之后的操作
        action.apply(this, arguments)
        // 将执行结果返回
        return result
    }
}

Function.prototype.before = function (action) {
    var func = this
    return function () {
        action.apply(this, arguments)
        return func.apply(this, arguments)
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let beforeFn = function () {console.log('beforeFn')}
let afterFn = function () {console.log('afterFn')}
let fn = function () {console.log('fn')}
fn.before(beforeFn).after(afterFn)()	// beforeFn fn afterFn

问题陈述

两个模块(A、B),由于两个模块相似度很高,且其中一个模块(A)是历史模块(已开发完成);所以我们采用 extends 方式,来扩展开发新的模块(B)。

历史 A 模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<el-button @click="submit">查询</el-button>
<script>
export default {
  name: 'A',
  methods: {
    submit () {
    	/* 主逻辑业务 */
    }
  }
}
</script>

现在,新模块(B)对于查询按钮的处理,需要发生变更,处理业务的同时需要发送相关日志。

对 A 模块进行改造,已适应新的方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<el-button @click="submit">查询</el-button>
<script>
export default {
  name: 'A',
  methods: {
    /* 将原有的逻辑业务代码进行抽离,便于新模块改造和沿用 */  
    submit () {
       this.submitReq()
    },
    submitReq () {
      /* 主逻辑业务 */
    }
  }
}  

新模块(B),覆盖默认submit 方法,进行日志处理,下面采用常规的静态代理模式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
  name: 'B',
  extends: 'A',
  methods: {
    /* 覆盖原有submit方法,增加日志采集处理 */
    submit () {
      // 这个来自于 A 模块
      this.submitReq()
  		this.recordLogReg()
    },
		recordLogReg () {}
  }
}

解决方案

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export default {
  name: 'B',
  extends: 'A',
  methods: {
    /* 覆盖原有submit方法,增加日志采集处理 */
    submit: this.submitReq.after(this.recordLogReg)(),
		recordLogReg () {
      /* 采集日志相关 */
    }
  }
}

每个函数变成了独立单元,可以随意组合,无需互相关联! 如果采用 class 写法,类的装饰器 decorator 也可以达到类似效果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年06月02日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于装饰器——我劝你不要在业务代码上装逼!!!
沉浸式趣谈
2024/03/13
1210
基于装饰器——我劝你不要在业务代码上装逼!!!
javascript设计模式十:装饰者模式
在js函数开发中,想要为现有函数添加与现有功能无关的新功能时,按普通思路肯定是在现有函数中添加新功能的代码。这并不能说错,但因为函数中的这两块代码其实并无关联,后期维护成本会明显增大,也会造成函数臃肿。
前端_AWhile
2019/08/29
4390
JavaScript设计模式与开发实践 - 高阶函数的应用
定义 高阶函数是指至少满足下列条件之一的函数: 函数可以作为参数被传递; 函数可以作为返回值输出。 JavaScript语言中的函数显然满足高阶函数的条件,在实际开发中,无论是将函数当作参数传递,还是让函数的执行结果返回另外一个函数,这两种情形都有很多应用场景,以下就是一些高阶函数的应用。 应用 作为参数传递 ajax异步请求 // callback为待传入的回调函数 var getUserInfo = function(userId, callback) { $.ajax("http://xxx
laixiangran
2018/04/11
8970
JavaScript高阶函数
把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等 可以保持业务逻辑模块的纯净和高内聚性
薛定喵君
2019/11/06
4620
JavaScript设计模式--装饰者模式
有时我们不希望某个类天生就非常庞大,一次性包含许多职责。那么我们就可以使用装饰着模式。 装饰着模式可以动态地给某个对象添加一些额外的职责,从而不影响这个类中派生的其他对象。 装饰着模式将一个对象嵌入另一个对象之中,实际上相当于这个对象被另一个对象包装起来,形成一条包装链。
奋飛
2019/08/15
4190
JS函数hook
我在阅读《JavaScript 设计模式与开发实践》的第 15 章 装饰者模式,突然发现 JS 逆向中 hook 函数和 js 中的装饰者模式有点像,仔细阅读完全篇后更是对装饰器与 hook 有了更深的理解于是便有了这篇文章来记录一下该操作。
愧怍
2022/12/27
3.6K0
在Javascript中进行面向切面编程
面向切面编程(Aspect-oriented programming,AOP)是一种编程范式。做后端 Java web 的同学,特别是用过 Spring 的同学肯定对它非常熟悉。AOP 是 Spring 框架里面其中一个重要概念。可是在 Javascript 中,AOP 是一个经常被忽视的技术点。
挥刀北上
2023/07/20
4380
在Javascript中进行面向切面编程
JS常用的几种设计模式
面试常常问到设计模式,设计模式在实际业务中即使有用到,但是依然感受不到它的存在,往往在框架中会有更多体现,比如vue2源码,内部还是有很多设计思想,比如观察者模式,模版模式等,我们在业务上一些通用的工具类也会用到单例,在大量的条件判断也会考虑策略者模式,这两种用得比较多。好记性不如烂笔头,又重新回顾了一遍设计模式,虽然仅仅掌握了几种熟悉的设计模式,但是希望在复杂的业务上,能想起那些不太常用的设计模式。
Maic
2022/12/21
7970
JS常用的几种设计模式
【说站】js装饰者模式是什么
在程序开发中,不希望某种类型天生庞大,一次承担很多责任,可以使用装饰者模型。装饰者的模式可以动态地给某个对象追加责任,不会影响从这个类中诞生其他对象。
很酷的站长
2022/11/24
4210
【说站】js装饰者模式是什么
从闭包和高阶函数初探JS设计模式
JavaScript是一门完整的面向对象的编程语言,JavaScript在设计之初参考并引入了Lambda表达式、闭包和高阶函数等特性。
小东同学
2022/07/29
5370
从闭包和高阶函数初探JS设计模式
介绍几个JavaScript设计模式及场景应用
当然我们可以用一个通俗的说法:设计模式是解决某个特定场景下对某种问题的解决方案。因此,当我们遇到合适的场景时,我们可能会条件反射一样自然而然想到符合这种场景的设计模式。
winty
2020/04/14
7450
几种常用设计模式的简单示例
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
编程三昧
2021/08/21
5840
几种常用设计模式的简单示例
JavaScript-设计模式·基础知识
《JavaScript 设计模式与开发实践》是去年在多看阅读上买的电子书,拖延症晚期患者在快一年后终于把这本书粗略读完,顺便做个笔记,加以总结,以便往后重新翻阅温习。
数媒派
2022/12/01
4350
超全60000多字详解 14 种设计模式 (多图+代码+总结+Demo)
沉浸式趣谈
2024/03/13
960
超全60000多字详解 14 种设计模式 (多图+代码+总结+Demo)
手撕常见JS面试题
高阶函数实现AOP(面向切面编程) Function.prototype.before = function (beforefn) { let _self = this; // 缓存原函数的引用 returnfunction () { // 代理函数 beforefn.apply(this, arguments); // 执行前置函数 return _self.apply(this, arguments); // 执行原函数
helloworld1024
2022/10/14
5370
Thinking--Normalize思想在前端中的应用
发组件过程中,为了提高组件的灵活性,我们通常需要支持多种传参格式,如何优雅的控制和组件内部解耦变得尤为重要!
奋飛
2019/08/14
3910
设计模式(11)[JS版]-JavaScript中的注解之装饰器模式
装饰器模式模式动态地扩展了(装饰)一个对象的行为,同时又不改变其结构。在运行时添加新的行为的能力是由一个装饰器对象来完成的,它 "包裹 "了原始对象,用来提供额外的功能。多个装饰器可以添加或覆盖原始对象的功能。装饰器模式属于结构型模式。和适配器模式不同的是,适配器模式是原有的对象不能用了,而装饰器模式是原来的对象还能用,在不改变原有对象结构和功能的前提下,为对象添加新功能。
AlbertYang
2020/09/08
8750
设计模式(11)[JS版]-JavaScript中的注解之装饰器模式
js中如何在不影响既有事件监听的前提下新增监听器
比如某个按钮已经绑定了2-3个对Window对象的load事件的监听,现在需要添加一个新的对click事件的监听器,但在一定条件下才会同时触发原有的2-3个load监听器,否则只触发新添加的这个事件。
大史不说话
2018/09/10
2.3K0
2023前端必会手写面试题整理1
我们说迭代器对象全凭迭代器生成函数帮我们生成。在ES6中,实现一个迭代器生成函数并不是什么难事儿,因为ES6早帮我们考虑好了全套的解决方案,内置了贴心的 生成器 (Generator)供我们使用:
helloworld1024
2023/01/03
5010
Thinking--IOC思想在前端中的应用
系统中,经常会出现 A 模块,依赖 B 模块,同时也依赖 C 模块的情况。我们通常的处理方式是将 B、C 模块直接引入到 A 模块中,这个获取过程都在 A 模块中实现,随着业务的扩充,A 模块可能还需要 D、E、F… 等等模块,这将导致代码高度耦合并且难以维护和调试。且未来想要删除某模块,需要删除模块的代码,同时需要删除在 A 模块中的引用。
奋飛
2019/08/14
6620
相关推荐
基于装饰器——我劝你不要在业务代码上装逼!!!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验