当前位置: 首页 > news >正文

JavaScript逆向Vue处理事件和捕获错误的核心逻辑

Vue处理事件和捕获错误的核心逻辑

  • 代码
  • 解释
    • 函数 at: 事件调用器工厂
      • 逻辑分解
      • 小结
    • 函数 Ue: 错误处理执行器
      • 逻辑分解
      • 小结
    • 它们如何协同工作

代码

在逆向一个Vue框架的前端代码时,发现一段反复出现的代码逻辑,这里做一个探究,我们直接上代码!

function Ue(e, t, n, r, o) {var i;try {(i = n ? e.apply(t, n) : e.call(t)) && !i._isVue && f(i) && !i._handled && (i.catch((function (e) {return Ve(e, r, o + " (Promise/async)")})),i._handled = !0)} catch (e) {Ve(e, r, o)}return i
}function at(e, t) {function n() {var e = arguments, r = n.fns;if (!Array.isArray(r))return Ue(r, null, arguments, t, "v-on handler");for (var o = r.slice(), i = 0; i < o.length; i++)Ue(o[i], null, e, t, "v-on handler")}return n.fns = e,n
}

解释

这段代码是 Vue.js 框架(很可能是 Vue 2)内部用于处理事件和捕获错误的核心逻辑。
简而言之,at 函数创建了一个“事件调用器”,而 Ue 函数是这个调用器用来安全执行具体事件处理函数(并捕获任何错误)的工具。

函数 at: 事件调用器工厂

这个函数是一个工厂函数,它的作用是创建一个用于 v-on 事件的包装函数(即“调用器”)。这个包装函数非常巧妙,它允许 Vue 动态地添加、删除或替换事件处理器,而无需操作真实的 DOM 事件监听器。

  • function at(e, t)
    • e: 真正的事件处理器。这可以是一个函数,也可以是一个函数数组(例如 v-on:click="[handler1, handler2]")。
    • t: 相关的 Vue 实例 (vm),会传递给 Ue

逻辑分解

  1. function n() { ... }:
    • 定义了一个新函数 n (我们称之为 invoker 或 “调用器”)。
    • 这个 invoker 函数是 at 最终返回的函数。它就是最终被绑定到 DOM 元素上的那个事件监听器。
  2. var e = arguments: 当 invoker 被(例如点击事件)调用时,e 会捕获所有的事件参数(比如 event 对象)。
  3. var r = n.fns
    • 这是最关键的部分。invoker 会从它自己的一个属性 .fns 上读取真正要执行的处理器
    • 这个 .fns 属性是在函数返回前被设置的。
  4. if (!Array.isArray(r)):
    • 检查 n.fns (即 r) 是不是一个数组
    • 如果不是数组(即只是一个单独的函数),就调用 Ue (错误处理执行器) 来执行这一个函数。
  5. for (...):
    • 如果 n.fns 一个数组,它会遍历这个数组。
    • var o = r.slice(): 复制数组以防止迭代过程中数组被修改。
    • Ue(o[i], null, e, t, "v-on handler"): 对数组中的每一个函数都调用 Ue 来安全地执行它。
  6. return n.fns = e, n:
    • n.fns = e: 把传入 at 的原始处理器 (e) 存储为 invoker 的一个属性 fns
    • return n: 返回这个 invoker 函数。

小结

它不直接执行事件,而是制造并返回另一个函数(invoker)。这个 invoker 被触发时,会查找自己 .fns 属性上的“真实”处理器(或处理器数组),然后使用 Ue 去安全地执行它们。

函数 Ue: 错误处理执行器

这个函数的核心目的是安全地执行一个函数,并捕获它在执行过程中可能抛出的同步错误异步 (Promise) 错误

  • function Ue(e, t, n, r, o)
    • e: 要执行的目标函数 (handler)。
    • t: 执行函数时的 this 上下文。
    • n: 传递给目标函数的参数数组。
    • r: 相关的 Vue 实例 (vm),用于错误报告。
    • o: 一个信息字符串,用于描述错误的来源 (例如 “v-on handler”)。

逻辑分解

  1. var i;: 声明一个变量 i,用来存放函数的执行结果。
  2. try { ... } catch (e) { ... }: 这是一个标准的 try...catch 块,用于捕获同步错误
  3. i = n ? e.apply(t, n) : e.call(t):
    • 这是实际执行函数的地方。
    • 如果 n (参数数组) 存在,就使用 e.apply(t, n) 来调用函数,并传入参数。
    • 如果 n 不存在,就使用 e.call(t) 来调用(无参数)。
    • i 被赋值为函数的返回值。
  4. i && !i._isVue && f(i) && !i._handled:
    • 这串检查是用来处理异步 (Promise) 错误的。
    • i: 检查函数是否有返回值。
    • !i._isVue: 确保返回值不是一个 Vue 实例。
    • f(i): 这是一个(未显示的)辅助函数,作用是检查 i 是否是一个 Promise
    • !i._handled: 确保这个 Promise 的错误还未被处理过。
  5. i.catch(...):
    • 如果上述所有条件都为真(即:函数返回了一个未处理的 Promise),它会给这个 Promise 挂载一个 .catch() 处理器。
    • 如果 Promise 被 reject(即发生异步错误),Ve 函数(一个全局错误处理器)会被调用,并附带上额外的信息 “(Promise/async)”。
    • i._handled = !0: 标记这个 Promise 已经被处理,防止重复捕获。
  6. catch (e):
    - 如果在执行同步函数时就出错,会立即进入这个 catch 块。
    - 调用 Ve 错误处理器,报告这个同步错误。
  7. return i:返回目标函数的原始返回值(可能是 undefined、一个值,或者那个 Promise)。

小结

它是一个健壮的函数执行器,能统一处理同步和异步 Promise 错误,并将它们报告给 Vue 的主错误处理系统 (Ve)。

它们如何协同工作

  1. 当 Vue 编译模板,遇到一个 v-on:click="myHandler" 时,它会调用 at(myHandler, vm)
  2. at 函数创建了一个 invoker 函数,并设置 invoker.fns = myHandler,然后返回这个 invoker
  3. Vue 将这个 invoker 绑定到 DOM 元素的 click 事件上。
  4. 当用户点击元素时,invoker 被触发。
  5. invoker 内部执行,它读取自己的 .fns 属性(即 myHandler)。
  6. invoker 调用 Ue(myHandler, null, arguments, vm, "v-on handler")
  7. Ue 负责在 try...catch 中执行 myHandler,并处理可能发生的任何同步或异步错误。

这种设计的最大好处是:如果 myHandler 后来改变了(例如在 data 中),Vue 只需要更新 invoker.fns = newHandler 即可,而不需要解绑和重新绑定 DOM 事件监听器,效率极高。

http://www.dtcms.com/a/569463.html

相关文章:

  • Python汤姆猫
  • Java中,直接使用null.equals()
  • GIS坐标系转换相关基本理论
  • 网站开发标书品牌网络推广方案
  • 门户网站制作服务ppt做的模板下载网站有哪些内容
  • Pycharm 中jupyter notebook变量窗口只显示特殊变量
  • 怀化优化生育政策seo怎么做优化排名
  • 1984年-2022年全球年度地表水扩张或消退时间数据集
  • 三乡网站开发网络营销的策略
  • APM学习(4):ArduPilot程序运行流程
  • seo站内站怎么做河北 网站建设
  • U-Boot零基础入门第二篇(如何看懂uboot目录?)
  • Javascript循环语句之while循环
  • BuildingAI 用户信息弹出页面技术架构
  • C#串口通讯助手
  • 企业网站icp备案建站哪家好
  • SparkSQL读取普通文件的方式
  • 网站平台推广方案网站内页如何做排名
  • 各个系统的 docker安装
  • 大庆建设网站表格下载建设一个网站需要哪些方面的开支
  • 各种网站建设报价制作网页网站的软件是
  • 在多阶段松弛实验中使用分布式光纤传感量化局部和非局部岩石变形
  • (ACP广源盛)GSV6172---MIPI/LVDS 信号转换为 Type-C/DisplayPort 1.4/HDMI 2.0 并集成嵌入式 MCU
  • 【每天一个AI小知识】:什么是少样本学习?
  • 建网站找那家企业好横岗网站建设公司
  • Vue面试项目经验分享:如何专业展示技术能力与解决问题
  • 浏阳网站开发顺德做网站的公司
  • 20、docker跨主机网络-Vxlan、vtep补充
  • CONCAT函数使用中出现空指针异常问题分析
  • 织梦网站挂马教程wordpress数据盘