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的做法);
相关推荐
2401_878454536 小时前
浏览器工作原理
前端·javascript
by__csdn8 小时前
Vue3 setup()函数终极攻略:从入门到精通
开发语言·前端·javascript·vue.js·性能优化·typescript·ecmascript
Luna-player9 小时前
在前端中,<a> 标签的 href=“javascript:;“ 这个是什么意思
开发语言·前端·javascript
lionliu05199 小时前
js的扩展运算符的理解
前端·javascript·vue.js
小草cys9 小时前
项目7-七彩天气app任务7.4.2“关于”弹窗
开发语言·前端·javascript
前端一小卒11 小时前
一个看似“送分”的需求为何翻车?——前端状态机实战指南
前端·javascript·面试
syt_101311 小时前
Object.defineProperty和Proxy实现拦截的区别
开发语言·前端·javascript
长安牧笛11 小时前
儿童屏幕时间管控学习引导系统,核心功能,绑定设备,设时长与时段,识别娱乐,APP超时锁屏,推荐益智内容,生成使用报告,学习达标解锁娱乐
javascript
栀秋66611 小时前
深入浅出链表操作:从Dummy节点到快慢指针的实战精要
前端·javascript·算法
青青很轻_12 小时前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js