js封装系列(一)

js封装系列(一)

适用场景

封装 sdk 场景下,在 sdk 中对公共对象以及方法进行 proxy 操作。

团队 A 有 A-sdk 对一个全局对象进行了改写 proxy 操作。此时,团队 B 开发了 B-sdk 对相同的全局对象的方法也进行了对应的改写。

出现问题

在一个项目中同时使用了 A-sdk 和 B-sdk,该项目研发同学在测试时发现 A 团队提供的 A-sdk 的对应功能失效了。

问题复现

创建原型

创建一个 base 工厂函数并配置对应的原型链方法 x

js 复制代码
// 原型
function base(){};
// 创建原型链方法
base.prototype.x = function(){
    return "base";
}

// 实例化
const baseEg = new base();

第一次劫持

模拟 A-sdk 劫持 x 方法,并添加一些业务逻辑

js 复制代码
const getX = baseEg.x;
baseEg.x = function(){
    return `proxy-${getX()}`;
}
baseEg.x(); // 输出 "proxy-base" 证明劫持成功

第二次劫持

模拟 B-sdk 劫持 x 方法,并添加 B 团队的业务逻辑

方案1
js 复制代码
// func1 实现
const func1GetX = baseEg.x;
baseEg.x = function() {
    return `func1-${func1GetX()}`;
}
baseEg.x();
// 输出 "func1-proxy-base"
方案2:
js 复制代码
// func2 实现
const func2GetX = Object.getPrototypeOf(baseEg).x;
baseEg.x = function() {
    return `func2-${func2GetX()}`;
}
baseEg.x(); // 输出 "func2-base"

综合对比

方案1 方案2
思路 基于当前对象上的某个方法进行封装 基于当前对象原型链上的某个方法进行封装
输出 "func1-proxy-base" "func2-base"
结论 不会破坏其他库对该方法的封装 基于原型链方法进行封装会破坏其他库对

至此问题已浮出水面。

警示

在封装sdk过程中:

  1. 尽量 不修改全局对象(遵循如无必要勿增实体的原则);
  2. 不要覆盖存在于原型链上的方法(上面方案2的做法);
  3. 提醒用户检查其他sdk是不是有类似的操作(上面方案2的做法);
相关推荐
玄空z几秒前
通俗理解 RAG 与微调:给大模型“翻书”还是“洗脑”
javascript
Devin_chen11 分钟前
单例模式渐进式学习指南
前端·javascript
阿民_armin34 分钟前
使用 IntersectionObserver + 哨兵元素实现长列表懒加载
前端·javascript·vue.js
ouzz1 小时前
使用 react-canvas 制作一个 Figma 工具:从画布到编辑器
前端·javascript
颜酱1 小时前
语音合成与视觉模型api接入实现
前端·javascript·人工智能
阿珊和她的猫2 小时前
使用 TypeScript 实现数组类型判断方法
javascript·typescript·状态模式
XTTX1102 小时前
Vue3+Cesium电子围栏效果
前端·javascript·vue.js
小高0073 小时前
🔥前端性能内卷终点?Signals 正在重塑我们的开发习惯
前端·javascript·vue.js
LXXgalaxy3 小时前
Vue3 列表数据流:从赋值入门到进阶(独立学习版)
javascript·vue.js·学习
zzginfo4 小时前
JavaScript 中 Array 、 Set 、 WeakSet 区别
开发语言·javascript·ecmascript