__proto__ 是所有对象(除null)的内部原型链接,指向其构造函数的 prototype;prototype 是函数独有的属性,用于定义实例共享的方法和属性,共同构成原型链。

搞清 __proto__ 和 prototype 的关系,是理解 JavaScript 原型链的起点。它们不是一对“同义词”,而是分工明确、归属不同、作用互补的两个机制。
谁拥有 prototype?只有函数
prototype 是函数对象(包括构造函数、普通函数、甚至 class)才有的属性,它是一个普通对象,用来定义该函数作为构造函数时,所有实例共享的属性和方法。
- 例如:
function Person() {}创建后,Person.prototype自动存在,类型为object - 给它添加方法:
Person.prototype.say = function() {},之后所有new Person()实例都能调用say - 普通对象(如
{}、new Date())没有prototype属性,访问会返回undefined
谁拥有 __proto__?所有对象(除 null)
__proto__ 是每个对象(包括函数、数组、字面量对象等)都具备的内部链接,指向它的原型对象——也就是它“从哪来的”。
- 实例对象的
__proto__指向其构造函数的prototype:const p = new Person(); p.__proto__ === Person.prototype - 函数本身也是对象,所以也有
__proto__:Person.__proto__ === Function.prototype - 就连
Function.prototype也有__proto__,最终指向Object.prototype -
Object.prototype.__proto__是null,这是整个原型链的终点
原型链怎么工作?属性查找靠 __proto__ 一层层向上
当你读取一个对象的属性(比如 obj.toString()),JS 引擎不会只看对象自己,而是按以下路径查找:
- 先查
obj自身是否有该属性 - 没有?就顺着
obj.__proto__找到它的原型对象,再查 - 还没找到?继续顺着那个原型对象的
__proto__往上找(即obj.__proto__.__proto__) - 直到
Object.prototype;若仍无,返回undefined
这个逐级委托的链条,就是原型链。它不依赖 prototype 直接参与查找,但 prototype 提供了链上的关键节点。
标准写法推荐:少碰 __proto__,多用标准 API
__proto__ 虽被广泛支持,但属于历史遗留的非标准属性。现代开发中应优先使用标准方法操作原型关系:
- 获取原型:
Object.getPrototypeOf(obj)(替代obj.__proto__) - 设置原型:
Object.setPrototypeOf(obj, proto)(替代赋值obj.__proto__ = ...) - 创建带指定原型的对象:
Object.create(proto) - 判断继承关系:
obj instanceof Constructor或Constructor.prototype.isPrototypeOf(obj)
prototype 则是标准且鼓励直接使用的——它是你为构造函数设计共享行为的主要入口。

















