原型污染可通过冻结关键原型、拦截defineproperty、统一polyfill和工厂函数替代全局挂载来防控:冻结array/object/eventtarget/promise.prototype;重写object.defineproperty拦截非法注入;主应用统一加载core-js并禁用子应用polyfill;工具方法改用独立函数或可注入工厂。

不同库往 Array.prototype、Object.prototype 或 EventTarget.prototype 等全局原型上添加方法,是典型的“原型污染”,会引发运行时行为不一致甚至崩溃。解决核心不是阻止所有扩展,而是控制谁可以改、改什么、何时生效。
冻结关键原型,切断非法写入
在主应用启动初期或子应用挂载前,主动冻结高频被污染的原型对象:
Object.freeze(Array.prototype)Object.freeze(Object.prototype)Object.freeze(EventTarget.prototype)Object.freeze(Promise.prototype)
冻结后,任何尝试向这些原型添加属性(如 Array.prototype.myMethod = ...)都会静默失败(严格模式下抛错)。注意:冻结只作用于当前对象层级,不影响已有实例,也不影响子原型链上的可写性。
拦截危险的 defineProperty 操作
有些库绕过直接赋值,改用 Object.defineProperty 注入属性。可在入口文件顶部加一层防护:
- 保存原生方法:
const originalDefineProperty = Object.defineProperty; - 重写为守门员:
Object.defineProperty = function(target, prop, descriptor) { if (target === Array.prototype || target === Object.prototype) return; return originalDefineProperty.apply(this, arguments); };
该拦截对子应用生效,但需确保它在所有第三方库初始化之前执行——通常放在 index.html 的 script 标签最顶部,或 webpack entry 的第一行。
统一 polyfill,避免多版本打架
冲突常源于多个库各自引入不同版本的 core-js 或自定义 polyfill。应由主应用统一加载并冻结环境:
- 主应用中一次性导入:
import 'core-js/stable'; - 禁用子应用自行引入 polyfill(构建时通过
webpack.NormalModuleReplacementPlugin替换掉相关模块) - 检查子应用打包产物,确认无重复的
Array.from、Promise.allSettled等补丁代码
统一后,所有应用共享同一套底层实现,不再因版本差异导致方法签名或返回值不一致。
用工厂函数替代全局挂载
若业务必须扩展原型(如工具方法),不要直接挂到全局原型上:
- 改为封装成独立函数:
export const isArrayLike = (val) => {...} - 或提供可注入的工厂:
const createUtils = (proto) => ({ extend: () => proto.myMethod = ... }); - 子应用调用时传入自己的空对象或局部原型,不触碰全局
这样既满足功能需求,又把影响范围限制在可控域内,避免跨应用污染。











