可通过tostring()输出或object.getownpropertydescriptor检测内置原型方法是否被重写:原生方法tostring含"[native code]"且configurable为false,重写后通常不满足这两点;还可缓存初始引用做===比对。

可以通过比对方法的 toString() 输出或使用 Object.getOwnPropertyDescriptor 检查其属性描述符,来判断内置原型方法(如 Array.prototype.push、Object.prototype.toString)是否被外部重写。
检查方法是否为原生函数
原生函数的 toString() 通常返回形如 "function push() { [native code] }" 的字符串。若被重写,内容会明显不同(如显示函数体、箭头函数或 undefined)。
- 用
Function.prototype.toString.call(obj.method)获取原始字符串表示 - 检测是否包含
"[native code]"(注意:不能仅靠正则匹配,需结合上下文,因某些 polyfill 或调试工具可能伪造) - 示例:不推荐仅靠
/\[native code\]/.test(fn.toString()),存在误判风险;应配合其他手段
检查属性是否可配置/是否为原始定义
内置原型方法默认是 configurable: false(不可删除、不可重新定义),若被重写,该属性往往变为 true 或直接丢失。
- 用
Object.getOwnPropertyDescriptor(Array.prototype, 'push')查看configurable和writable字段 - 原生方法通常为
{ value: ..., writable: true, enumerable: false, configurable: false } - 若
configurable为true,大概率已被覆盖(例如通过Array.prototype.push = function(){...})
对比构造器或原型链上的原始引用
保存一份“可信快照”(如页面加载初期),后续与当前方法做严格相等(===)比对。
- 在代码最前(如
<script></script>开头)缓存:const originalPush = Array.prototype.push; - 后续检测:
Array.prototype.push === originalPush - 适用于可控环境(如 SDK、监控脚本),无法用于已运行的第三方重写场景
注意边界情况和局限性
某些重写方式难以 100% 可靠识别,例如:
- 通过
Object.defineProperty以configurable: false重新定义同名方法(极少见,但技术上可行) - 使用
Proxy包裹原型对象(此时方法调用仍走原生逻辑,但行为可拦截) - 某些浏览器扩展或调试工具会静默劫持方法(如 DevTools 注入的 override)
-
Function.prototype.toString本身也可能被篡改,导致检测失效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











