原型链是JavaScript对象行为的底层逻辑,决定属性查找、方法调用与继承机制;prototype是函数的共享配置对象,__proto__是实例指向其构造函数prototype的内部链接,查找沿链单向进行至Object.prototype终止。

原型链不是“高级技巧”,而是 JavaScript 对象行为的底层逻辑。它直接决定属性怎么找、方法怎么用、继承怎么发生——不理解它,写出来的面向对象代码容易出错、难调试、难复用。
prototype 和 __proto__ 不是同一个东西,但它们连成一条线
每个函数(非箭头函数)自带 prototype 属性,它是一个对象,专为实例共享而设;每个对象(除 null)都有内部属性 [[Prototype]],在多数环境中可通过 __proto__ 访问,它指向创建该对象的构造函数的 prototype。
-
Person.prototype是函数的“出厂配置说明书” -
new Person().__proto__是实例的“说明书查阅入口” -
Person.prototype.constructor === Person保证说明书能反查到原厂
查找过程是单向、线性、有终点的
访问 obj.xxx 时,引擎按固定路径搜索:obj 自身 → obj.__proto__ → obj.__proto__.__proto__ → …… 直到 Object.prototype,它的 __proto__ 是 null,链在此终止。
- 找不到就返回
undefined,不会报错 - 中间某层定义了同名属性,会“屏蔽”更上层的同名属性(就近原则)
- 所有数组、日期、正则等内置对象,都靠这条链继承
toString()、valueOf()等通用方法
继承不是复制,是动态委托
通过 Child.prototype = Object.create(Parent.prototype) 建立原型链后,子类实例调用父类方法时,并不是把方法拷贝过来,而是运行时沿着链实时查找并执行。
立即学习“Java免费学习笔记(深入)”;
- 修改
Parent.prototype.method,所有已存在和将创建的子类实例立刻生效 - 避免用
Child.prototype = new Parent()—— 它会执行父类构造逻辑,可能引发副作用或状态污染 - 记得补上
Child.prototype.constructor = Child,否则 constructor 会指向 Parent
高效代码的关键在于“少写、准写、可预期”
把方法挂到 prototype 上,而不是每次构造都重复创建;把共享数据放 prototype(仅限原始值),引用类型要小心初始化位置;优先用 Object.getPrototypeOf() 替代 __proto__,更标准也更安全。
- 避免在原型上放可变对象(如
{list: []}),否则所有实例共用同一份数组 - 判断属性是否自有,用
obj.hasOwnProperty('x')或Object.prototype.hasOwnProperty.call(obj, 'x') - ES6 class 本质仍是原型链语法糖,
class A extends B底层仍靠Object.setPrototypeOf(A.prototype, B.prototype)实现


















