javascript原型继承的坑在于行为反直觉,核心是理解原型链为属性查找路径而非模板复制;须用object.create(father.prototype)继承并修复constructor,避免共享引用和this绑定错误。

JavaScript原型继承看着简单,实际踩坑频率很高。核心问题不是“写不出来”,而是“写出来但行为反直觉”——比如改了一个实例的数组,另一个实例也跟着变了;或者明明调用了方法,却报 undefined is not a function。避开这些坑,关键在于理解原型链是“属性查找路径”,而不是“类模板复制”。
别直接赋值 Son.prototype = Father.prototype
这是最隐蔽也最危险的操作。它让子类和父类共用同一个原型对象,任何对 Son.prototype 的修改(比如加方法)都会直接影响 Father.prototype,导致父类实例意外获得子类方法。
- 错误写法:
Son.prototype = Father.prototype; - 正确做法:用
Object.create(Father.prototype)创建一个新对象,只继承父类原型上的属性和方法,不共享引用 - 补充:创建后记得修复 constructor,
Son.prototype.constructor = Son;,否则new Son()实例的 constructor 会指向Father
别用 new Father() 直接赋给子类原型
看似合理,实则埋雷。这样做会让所有子类实例共享父类构造函数中定义的引用类型属性(如数组、对象),因为它们都从同一个父类实例继承而来。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 典型症状:
son1.arr.push(1)后,son2.arr也多出一个元素 - 根本原因:父类实例的
this.arr = []是引用值,被所有子类原型共享 - 解法:改用
Object.create(Father.prototype),避免执行父构造函数;属性初始化交给子构造函数内部的Father.call(this, ...)
别忽略 constructor 指向丢失
只要重写了子类的 prototype(无论是 Object.create 还是 new Father()),它的 constructor 就会断掉,默认指向 Object 或 Father,影响 instanceof 判断和调试时的类型识别。
- 验证方式:
console.log(Son.prototype.constructor === Son); // false - 必须手动补上:
Son.prototype.constructor = Son; - ES6 class 自动处理这点,但手写原型继承时绝不能跳过
别混淆 this 绑定与原型查找
原型链解决的是“方法在哪能找到”,而 this 决定的是“方法执行时上下文是谁”。两者独立运行,但常被一起误判。
- 常见翻车:把原型上的方法赋给变量再调用,
const fn = son.sayHello; fn();→this变成undefined(严格模式)或window - 这不是原型问题,是调用方式问题。修复靠
.bind、箭头函数,或确保用son.sayHello()形式调用 - 记住:原型链只管“找得到”,不管“调得对”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










