亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 基础

  • 手写代码

    • 手写类型转换
    • 手写累加、累乘函数
    • 手写new
    • 手写深拷贝
    • 手写Object.create
    • 手写继承
    • 手写extends
    • 手写instanceof
    • 手写call、apply、bind
    • 手写jsonp
    • 手写getQueryString
    • 手写setInterval
    • 手写防抖与节流
    • 手写对象属性值迭代器
    • 手写分时函数
    • 手写事件委托
    • 手写图片懒加载
    • 手写原生Ajax请求
    • 手写AOP装饰函数
      • 应用场景
    • 手写柯里函数
    • 手写数组扁平化flat
    • 手写数组去重
    • 手写eventEmit类
    • 手写Vue数据响应式
    • 手写Vue nextTick
    • 手写Promise
  • JS底层深入

  • CSS

  • 基础
  • 手写代码
0zcl
2021-06-18
目录

手写AOP装饰函数

注意

实现一个AOP装饰函数

答:

Function.prototype.before = function(beforeFn) {
  const context = this // 原函数
  return function() { // 返回一个装饰函数
    beforeFn.apply(this, arguments)
    return context.apply(this, arguments)
  }
}

Function.prototype.after = function(afterFn) {
  const context = this
  return function() {
    const res = context.apply(this, arguments)
    afterFn.apply(this, arguments)
    return res
  }
}
// 测试
function test() {
  console.log(2, arguments)
}
var aopTest = test
.before(function(){
  console.log(1, arguments)
})
.after(function() {
  console.log(3, arguments)
})
console.log(aopTest('zcl'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

aop

注意:

  1. 执行<code>Function.prototype.before</code>、<code>Function.prototype.after</code>函数,会返回装饰函数
  2. 注意<code>this</code>指向,aop函数的beforeFn,afterFn的<code>this</code>指向和<code>参数</code>,与最终执行的装饰函数是一致的

# 应用场景

  • 数据上报,埋点
const submit = function() {
  console.log('点击提交')
}
const log = function() {
  console.log('记录点击次数')
}
submit.after(log)()
1
2
3
4
5
6
7

分离<code>业务代码</code>和<code>埋点代码</code>

  • 表单验证
Function.prototype.beforeValidate = function(beforeFn) {
  const context = this
  return function() {
    // beforefn 返回 false 的情况直接 return,不再执行后面的原函数
    if (beforeFn.apply(this, arguments) === false) return
    return context.apply(this, arguments)
  }
}
// 较验用户密码不能为空
const validate = function() {
  if (userName === '') return false
  if (password === '') return false
  return true
}
const submit = function () {
  // ..... 业务操作
}
submit.beforeValidate(validate)()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

分离<code>较验输入</code>和<code>业务代码</code>

参考: [JavaScript设计模式与开发实践]

编辑 (opens new window)
上次更新: 2025/07/20, 06:21:22
手写原生Ajax请求
手写柯里函数

← 手写原生Ajax请求 手写柯里函数→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式