JavaScript继承基于原型链而非类复制,实例通过[[Prototype]]隐式链接到构造函数的prototype,最终指向Object.prototype终止;ES6 class底层仍是原型链但自动处理constructor修复和super等细节。

JavaScript 的面向对象继承不是靠“类复制”,而是靠对象之间隐式链接形成的查找路径——也就是原型链。理解它,关键不在记语法,而在看清属性和方法是怎么一层层被找到的。
原型链怎么连起来的
每个函数(非箭头函数)都有一个 prototype 属性,它是一个普通对象,默认带一个 constructor 指向自身。当你用 new Parent() 创建实例时,该实例内部的 [[Prototype]](可通过 Object.getPrototypeOf() 或非标准的 __proto__ 访问)会自动指向 Parent.prototype。
要让子类复用父类方法,只需把子类的原型设为父类的一个实例:
- Child.prototype = new Parent();
- 此时新创建的 const c = new Child(),其 [[Prototype]] → Child.prototype → Parent.prototype → Object.prototype → null
- 必须手动修复:Child.prototype.constructor = Child;,否则 c.constructor 会指向 Parent
方法复用和属性隔离的区别
写在 Parent.prototype 上的方法(比如 sayName()),所有子类实例共享同一份函数体,不占额外内存,也互不影响。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
但构造函数里定义的实例属性,行为完全不同:
- 引用类型(如 this.colors = ['red'])会被所有子类实例共享——改一个,其他全变
- 基本类型(如 this.name = 'parent')可读,但一旦赋值(c1.name = 'child'),就在实例上新建属性,屏蔽原型上的同名值
为什么终点一定是 Object.prototype
几乎所有对象的原型链最终都会抵达 Object.prototype,因为它是 JavaScript 中绝大多数内置对象和自定义对象的顶层原型。它的 [[Prototype]] 是 null,表示查找终止。这也是 toString()、hasOwnProperty() 等通用方法能被所有对象调用的原因——它们就定义在这里。
常见陷阱和现代写法
手动操作原型链容易出错:
- 子类无法向父类构造函数传参(new Parent() 在设置原型时就执行了)
- 没有 super 机制,调父方法得写 Parent.prototype.method.call(this)
- 多层继承会让原型链变长,影响属性查找性能
ES6 的 class 和 extends 底层仍是原型链,但自动处理了 constructor 修复、super 支持、静态方法继承等细节,日常开发更推荐使用。

















