javascript继承核心是原型链,通过prototype与[[prototype]]连接;原型链继承共享方法但属性互相影响;组合继承结合call与原型链解决缺陷;class/extends是其语法糖,优化了可读性与功能。

JavaScript对象继承体系不是靠“类声明”堆出来的,而是靠原型链一层层连起来的。核心就两点:每个函数有 prototype,每个实例有隐式 [[Prototype]](通常通过 __proto__ 或 Object.getPrototypeOf() 访问),两者连上,就形成可查找的链。
原型链继承:最基础也最容易踩坑的方式
把父构造函数的实例赋给子构造函数的 prototype,子实例就能顺着链访问父原型上的方法。
- 能继承父类原型上的方法(比如
sayName()),写一次,多个实例共用 - 所有子实例共享父构造函数中创建的引用类型属性(如
this.colors = ['red'])——改一个,全跟着变 - 子类实例化时无法向父构造函数传参(
new Child('Alice')无法让父类收到 'Alice') - 父类构造函数里的初始化逻辑(比如计数器、私有状态)会被所有子类实例间接“共用”,不安全
原型模式本身:适合轻量共享,不适合复杂对象建模
不涉及继承,只是用构造函数 + prototype 组合来复用方法。这是 JavaScript 最自然的对象创建方式之一。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 每个实例拥有独立的基本类型属性(如
this.name),互不影响 - 所有实例共享
prototype上的方法,节省内存 - 不能封装私有变量或实现真正的“实例私有方法”
- 修改
prototype是动态的,运行时加方法或覆盖原有方法都有效,但也容易被意外篡改
真正实用的继承结构:组合继承是经典解法
单独用原型链或只用构造函数调用都有明显短板。组合继承把两者拼起来:用 Parent.call(this, ...) 拷贝实例属性,再用 Child.prototype = new Parent() 接上原型链。
- 子实例有各自独立的属性(包括引用类型),不会互相污染
- 能访问父类原型上的方法,保持复用性
- 支持子类构造时向父类传参(
new Child('张三', 25)) - 缺点是父构造函数会执行两次(一次在
call,一次在new Parent()),但现代 JS 引擎对此优化较好,实际影响不大
现代写法推荐:class + extends(语法糖,底层仍是原型)
ES6 的 class 不是新机制,它只是把上述组合继承包装得更清晰:
-
extends自动处理原型链连接和super()调用 -
super()确保父构造函数只执行一次,且 this 绑定正确 - 支持静态方法、getter/setter、私有字段(
#field)等增强特性 - 可读性强,协作友好,是当前工程实践的主流选择
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










