JavaScript中没有类继承,只有基于__proto__的委托查找;原型链是通过__proto__逐级向上查找属性的过程,prototype仅在new调用时用于设置新对象的__proto__。

JavaScript 中没有“类继承”,只有对象之间的委托关系;所谓原型链,就是从一个对象出发,通过 __proto__(或 Object.getPrototypeOf())逐级向上查找属性和方法的过程。
每个函数都有 prototype,但只有函数被用作构造器时它才起作用
声明一个函数时,JS 引擎会自动给它挂上 prototype 属性,值是一个普通对象,带一个 constructor 指回该函数。但它本身不参与任何查找——除非你用 new 调用这个函数。
此时,新对象的 __proto__ 会被设为该函数的 prototype 对象。
-
function Foo() {}→Foo.prototype存在,但没被任何对象直接链接 -
const f = new Foo()→f.__proto__ === Foo.prototype成立 -
const o = {}→o.__proto__ === Object.prototype,不是Function.prototype
__proto__ 和 prototype 完全不是一回事
__proto__ 是每个对象(包括函数)都有的内部属性,指向它的原型对象;prototype 是只有函数对象才有的属性,用于指定将来用 new 创建实例时,那些实例的 __proto__ 该指向谁。
立即学习“Java免费学习笔记(深入)”;
- 误写
obj.prototype.something:普通对象没有prototype属性,会得undefined - 误写
Func.__proto__.method:这查的是函数自身的原型(即Function.prototype),不是它实例的原型 - 现代写法应优先用
Object.getPrototypeOf(obj)替代obj.__proto__,后者是遗留 API
属性查找走的是 __proto__ 链,不是“作用域链”或“闭包链”
当你访问 obj.prop,JS 引擎先在 obj 自身找,找不到就去 obj.__proto__ 找,再找不到就继续找 obj.__proto__.__proto__,直到碰到 null(即 Object.prototype.__proto__)为止。
- 如果某层原型上有同名属性(比如
toString),就会“遮蔽”更上层的定义,不会合并或叠加 - 修改
obj.__proto__.x = 1会影响所有共享该原型的对象,但不推荐直接改,容易引发意外共享 -
for...in遍历包含原型链上的可枚举属性;Object.keys()只返回自身可枚举属性
真正容易出问题的地方在于:把 prototype 当成实例的“父类模板”来理解,而忽略了它只是被 new 复制过去的一次性链接目标;一旦原型被替换(比如重赋值 Foo.prototype = {}),已创建的实例不会自动更新 __proto__,它们仍指向旧的 prototype 对象。











