安全挂载全局工具的关键是隔离作用域、控制入口、留检测机制:不污染原生原型,优先用静态类或工厂函数;必须增强时加存在性检查与命名前缀,并配合冻结和校验。

挂载全局工具时避免 prototype 版本冲突,关键不是“能不能挂”,而是“挂到哪”和“谁来管”。直接往 Array.prototype 或 Object.prototype 上加方法,等于把钥匙交给所有模块——一旦两个库都定义了 .toJSON() 或 .compact(),行为就不可控。真正安全的做法是隔离作用域、控制入口、留出检测机制。
只扩展你完全掌控的类,不碰原生构造器
原生类型(Array、Object、Function)的 prototype 是共享战场,任何第三方脚本都可能修改它。生产环境应默认禁用这类操作。
- 把工具方法封装进自定义类,比如
class Utils { static deepClone() { } },调用时走Utils.deepClone(obj),不污染原型链 - 若必须增强内置类型,仅限未实现的标准方法,且加存在性检查:
if (!Array.prototype.at) { Array.prototype.at = function() { } } - 禁止在子应用或插件中执行
Object.prototype.myExtend = …这类语句;构建时可用 ESLint 规则no-extend-native拦截
用工厂函数或注入方式替代全局挂载
全局变量(window.utils、window.$)看似方便,实则让版本管理失效。不同子应用加载不同版本的工具包,最终只有一个生效,其余被覆盖。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 主应用统一提供工具实例,通过 props 或 context 注入子应用,例如
<subapp utils="{sharedUtils}"></subapp> - 改用工厂函数:子应用调用
createUtils({ version: '2.1' })获取专属实例,彼此隔离 - 微前端场景下,禁用子应用向
window写入工具属性;qiankun 沙箱虽不能拦截原型写入,但可配合import 'core-js/stable'统一 polyfill,减少重复补丁
挂载前冻结 + 检测 + 命名隔离
如果业务强依赖原型方法(如某些 UI 库内部逻辑),必须挂载,那就得加三道保险。
立即学习“Java免费学习笔记(深入)”;
- 在挂载前冻结目标原型:
Object.freeze(Array.prototype)(需在所有脚本前执行) - 挂载时加前缀并检测:
if (!Array.prototype.mylib_mapAsync) { Array.prototype.mylib_mapAsync = function() { } } - 用
Symbol或私有字段模拟增强,避免暴露到原型链上,例如:obj[Symbol.for('mylib-cache')] = {}
动态加载时确保构造与原型同轮次初始化
通过 import() 或 eval 加载工具脚本时,常见错误是构造函数和它的 prototype 方法分属不同执行块,导致实例找不到方法。
- 一个模块内完成定义与扩展:
class Formatter { } Formatter.prototype.format = function() { }; - 避免拆成两个动态脚本:A.js 定义
class Formatter,B.js 补Formatter.prototype.format—— B 必须明确等待 A 执行完毕 - 加载后轻量校验:
if (typeof Formatter.prototype.format !== 'function') throw new Error('Formatter format method missing');

















