“xxx is not a function”报错主因是原型链断裂或方法未定义在正确位置,需用console.log(obj.constructor)和obj.__proto__逐级验证对象真实类型与原型链,确认方法所在层级并排查Object.create(null)、原型重写等断链操作。

遇到“xxx is not a function”这类报错,往往不是方法写错了,而是调用对象的原型链上压根没这个方法——排查关键就是顺着 __proto__ 一层层查,确认方法到底该在哪一级定义、是否被覆盖或丢失。
看清楚调用对象的真实构造函数和原型
别只看字面变量名,先用 console.log(obj.constructor) 和 console.log(obj.__proto__) 确认对象实际类型和直接原型。比如:
-
数组误当普通对象用:若
arr = [1,2,3],但写了arr.map(...)报错,先检查arr.constructor === Array和arr.__proto__ === Array.prototype是否成立;不成立说明它已被赋值为其他对象(如arr = {length: 0}),自然没有map。 -
类实例被手动改过原型:执行过
obj.__proto__ = null或Object.setPrototypeOf(obj, someOtherProto),会直接切断原有继承链。
逐级向上检查方法是否存在
从对象自身开始,沿 __proto__ 向上查,直到 null:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
- 先查
obj.hasOwnProperty('methodName')—— 方法是否在实例自身上(少见,一般不推荐)。 - 再查
'methodName' in obj—— 是否在原型链任意一级(包括继承来的)。 - 手动打印链路:
console.log(obj.__proto__, obj.__proto__.__proto__, obj.__proto__.__proto__.__proto__),对照 MDN 文档确认标准原型结构(如Array → Object → null)。 - 用
obj.__proto__.hasOwnProperty('methodName')锁定具体在哪一级定义(例如push在Array.prototype,toString在Object.prototype)。
警惕常见“断链”操作
这些写法会隐式破坏原型链,导致方法消失:
立即学习“Java免费学习笔记(深入)”;
-
用字面量重写原型:如
MyClass.prototype = { method() {} }—— 这会丢掉默认的constructor和__proto__指向Object.prototype的关系,新实例无法访问toString等基础方法。 -
ES6 class 中错误定义静态方法:把本该在原型上的实例方法写成
static method(),调用时就会报“not a function”,因为instance.method找的是原型,不是类本身。 -
使用
Object.create(null)创建对象:这种对象原型是null,完全不继承任何方法,连hasOwnProperty都没有。
快速验证与修复建议
发现方法缺失后,按优先级处理:
- 确认调用对象类型是否符合预期(
Array.isArray(obj)、obj instanceof MyClass)。 - 如果是自定义类,检查
prototype是否被完整设置,必要时补回constructor:MyClass.prototype.constructor = MyClass。 - 避免直接操作
__proto__,改用Object.setPrototypeOf(obj, proto)并确保目标proto链路完整。 - 调试时可临时加保护:
if (typeof obj.method === 'function') { obj.method() },避免运行时报错中断流程。

















