可通过 Object.getOwnPropertyDescriptor 检查属性是否被隐藏(如 enumerable: false),再用 Object.getPrototypeOf 沿原型链追溯定位原始方法,最后用 Object.defineProperty 精确还原其 descriptor 特性。

可以通过 Object.getOwnPropertyDescriptor 检查属性是否被“隐藏”(如设为 enumerable: false 或被重写),再结合 Object.getPrototypeOf 向上追溯原型链,定位原始方法定义位置,最后手动还原。
确认目标方法是否被枚举性屏蔽
很多库(如某些 polyfill 或调试工具)不删除方法,而是将 enumerable 设为 false,导致 for...in 或 Object.keys() 看不见它,但方法仍可调用。用 getOwnPropertyDescriptor 可直接看到真实状态:
- 例如检查
Array.prototype.find是否被改写: Object.getOwnPropertyDescriptor(Array.prototype, 'find')- 若返回
{ value: fn, writable: true, enumerable: false, configurable: true },说明它还在,只是不可枚举 - 若返回
undefined,说明该属性在当前对象上已被删除或从未定义,需查原型链
沿原型链逐层查找原始定义
被“抹除”的方法往往只是在实例或子构造函数的 prototype 上被覆盖或设为 undefined,原始实现仍在更上层(如 Array.prototype → Object.prototype 或内置原型)。可用循环 + Object.getPrototypeOf 追溯:
- 对任意数组实例
arr,查找find的真实来源: let obj = arr;while (obj && !Object.getOwnPropertyDescriptor(obj, 'find')) { obj = Object.getPrototypeOf(obj); }const desc = Object.getOwnPropertyDescriptor(obj, 'find');- 一旦
desc存在且desc.value是函数,就找到了原始方法
安全还原被覆盖/删除的方法
还原不等于简单赋值,需尊重原有属性特性(writable、configurable、enumerable)。推荐用 Object.defineProperty 精确复刻 descriptor:
- 假设从
Array.prototype找到原始find描述符origDesc: Object.defineProperty(Array.prototype, 'find', origDesc);- 若原
configurable: false,则无法还原到其他对象上;但可在可配置的对象(如新建的空数组原型)中模拟 - 若第三方库用
Array.prototype.find = undefined,这属于“赋值覆盖”,descriptor 仍存在,还原即恢复原函数 - 避免用
Array.prototype.find = origDesc.value—— 这会丢失enumerable和configurable等关键元信息
识别典型“伪抹除”模式
有些库并不真正删除方法,而是通过非常规方式干扰访问,需针对性识别:
- 代理拦截:若对象是
Proxy,getOwnPropertyDescriptor可能返回假值,需检查obj.constructor和Object.isProxy(obj) - 冻结/封印:若
Object.isFrozen(Array.prototype)为true,则无法还原;此时只能在非冻结对象上挂载替代方法 - 全局污染检测:对比
Array.prototype.find === Array.prototype.find是否恒等,若不等,大概率被中间件重写了 - 严格模式下隐式删除:某些老库在严格模式中执行
delete Array.prototype.find,此时 descriptor 返回undefined,需回退到标准内置行为(如用Array.from(arr).find(...)替代)

















