禁止修改对象的__proto__,尤其不得污染object.prototype等内建原型;应优先使用object.create构建干净原型链,或采用工具函数、symbol、proxy等安全方式扩展行为。

直接修改对象的 __proto__ 是高危操作,极易污染原型链、覆盖内建方法(如 toString、valueOf、hasOwnProperty 等),导致后续任意代码调用这些方法时行为异常甚至崩溃。根本原则是:**不改 __proto__,尤其不向 Object.prototype 或内置构造函数原型上添加/覆盖属性。**
优先使用 Object.create 构建干净原型链
若需继承特定行为,应显式创建新原型对象,而非篡改已有实例的 __proto__:
- ✅ 正确:用
Object.create(parentProto)创建新对象,其内部 [[Prototype]] 指向指定原型,完全隔离 - ❌ 危险:对已有对象执行
obj.__proto__ = someProto,可能意外覆盖该对象已有的同名方法,或污染后续所有从同一原型派生的对象 - 示例:需要带
log()方法的对象,应写const obj = Object.create({ log() { console.log(this); } });,而非给某个活对象动态改__proto__
绝对禁止向 Object.prototype 或 Array.prototype 等内建原型添加属性
向 Object.prototype 添加方法(如 Object.prototype.myUtil = ...)会使 所有 对象都继承它,极易与未来标准方法、第三方库方法、甚至 for-in 循环中的预期行为冲突:
- for-in 遍历时会枚举出你加的属性,除非用
Object.defineProperty显式设为enumerable: false - 若恰好命名与某新标准方法重名(如曾有人加过
Object.prototype.values,后 ES2017 原生加入同名方法),就会覆盖原生实现 - 现代框架(React、Vue)内部高频调用
hasOwnProperty等方法,一旦被覆盖,轻则渲染失败,重则静默卡死
如必须扩展行为,用组合或 Symbol 属性替代原型污染
业务中真正需要的是“能力”,不是“挂到原型上”:
- 用工具函数:如
log(obj)、deepClone(obj),明确作用域,无副作用 - 用
Symbol定义非字符串键:如obj[Symbol.for('myExtension')] = { log() { ... } },避免命名冲突 - 用类封装:定义
class EnhancedObj extends Object {}(注意:不能直接继承 Object,但可模拟;更推荐组合+工厂函数) - ES6+ 可用
Proxy拦截读写,按需注入行为,不侵入原型链
上线前做原型链完整性检查
在关键环境(如 CI 或启动时)运行轻量校验,快速发现污染:
- 检查
Object.prototype是否多了非标准自有属性:Object.getOwnPropertyNames(Object.prototype).filter(k => !['toString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf'].includes(k)) - 检查常用方法是否仍为原生函数:
Object.prototype.toString.toString().includes('[native code]') - 将上述逻辑封装为启动钩子,任一失败即报错退出,避免带病上线











