原型上存放引用类型会导致实例间数据污染,应将数组、对象等状态放构造函数中实例化,方法才放原型;需过滤__proto__等敏感键并冻结原生原型兜底。

原型属性被实例直接修改引发全局污染,本质是误把引用类型放在原型上,又用可变操作(如 push、obj.key = val)改了共享内存地址。避免的关键不是“锁住”原型,而是从设计源头切断共享路径。
引用类型别放原型上
数组、对象、日期等引用类型一旦定义在原型上,所有实例都指向同一块内存。哪怕只改一个实例的属性,其他实例立刻“感知”到变化。
- ❌ 错误写法:在原型上初始化引用数据
Animal.prototype.tags = [];
Animal.prototype.config = { timeout: 5000 };
- ✅ 正确做法:在构造函数中为每个实例单独创建
function Animal(name) {
this.name = name;
this.tags = [];
this.config = { timeout: 5000 };
}
这样每个实例都有独立副本,互不干扰。
方法放原型,状态归实例
原型适合存放函数——函数是只读的,调用时不会改变原型本身;而数据状态(尤其是可变的)必须属于实例自身。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 方法可以复用:所有实例共用同一个函数引用,节省内存
- 状态必须隔离:姓名、计数器、列表等,每个实例应有一份专属拷贝
- 混淆会导致“看似正常,实则错乱”的 bug,比如两个表单组件共用一个
errors数组
警惕隐式污染场景
有些操作表面看是“读取”,实际触发了原型写入:
- 服务端返回 JSON 后直接
Object.assign(instance, data)—— 若 data 含{"__proto__": {...}},会污染整个原型链 - 使用老旧版本 lodash.merge 处理用户输入,未开启安全选项
- 手动递归合并对象时,没过滤
__proto__、constructor、prototype等敏感键
建议统一用白名单校验字段名,或改用 structuredClone()(现代环境)做深拷贝。
冻结关键原型作为兜底防线
即使业务层规范,第三方库或意外代码仍可能尝试污染。可在应用入口尽早冻结原生原型:
Object.freeze(Object.prototype);
Object.freeze(Array.prototype);
Object.freeze(Function.prototype);
注意:必须在任何第三方脚本加载前执行;它不能替代正确设计,但能阻断大多数恶意写入。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










