← [ BACK_TO_NOTES ]

proto-prototype-constructor

__proto__、prototype、constructor 三者关系拆解。

#concept #growing #javascript #ecmascript

[!info] related notes

__proto__、prototype、constructor 三者关系

一句话定义

  • __proto__ 是每个实例指向其构造函数 prototype 的链接(原型链的连接线)
  • prototype 是构造函数独有的属性,存放所有实例共享的方法
  • constructor 是 prototype 上的属性,指回构造函数本身

核心机制 / 工作原理

三者的关系图

function Foo() {}

foo = new Foo()

  foo.__proto__  ----->  Foo.prototype
                          |
                          | .constructor
                          |
                          v
                        Foo

核心等式

function Foo() {}
const foo = new Foo();

// 1. 实例的 __proto__ 指向构造函数的 prototype
foo.__proto__ === Foo.prototype;          // true

// 2. prototype 上的 constructor 指回构造函数
Foo.prototype.constructor === Foo;        // true

// 3. 由此推导
foo.__proto__.constructor === Foo;        // true
foo.constructor === Foo;                  // true(沿原型链查找到)

prototype 链的逐级查找

foo.hasOwnProperty('toString')  // false
// 查找过程:
// 1. foo 自身没有 toString
// 2. foo.__proto__ (= Foo.prototype) 没有 toString
// 3. Foo.prototype.__proto__ (= Object.prototype) 找到了 toString

完整链:foo -> Foo.prototype -> Object.prototype -> null

constructor 不是”自带的”

constructor 是在创建函数时,JS 引擎自动在 Foo.prototype 上设置的。但如果手动覆盖了 prototype:

Foo.prototype = {}; // 覆盖了整个 prototype
// 此时 Foo.prototype.constructor 丢失,变成 Object
// 修复:Foo.prototype.constructor = Foo;

最小例子

function Person(name) {
  this.name = name;
}
Person.prototype.greet = function () {
  return 'Hi, ' + this.name;
};

const p = new Person('Alice');

// 验证三者关系
p.__proto__ === Person.prototype;           // true
Person.prototype.constructor === Person;    // true
p.__proto__.constructor === Person;         // true

// 原型链查找
p.greet();          // 'Hi, Alice'  — 从 Person.prototype 上找到
p.constructor;      // Person       — 从 Person.prototype.constructor 找到
p instanceof Person; // true

边界与常见误解

  • “每个对象都有 prototype” — 错。只有函数才有 prototype 属性。普通对象只有 __proto__。
  • “__proto__ 是标准” — __proto__ 是非标准的访问方式(虽然所有浏览器都支持)。标准方式是 Object.getPrototypeOf(obj)。
  • “constructor 是只读的” — 不是。constructor 可以被覆盖,覆盖后 instance.constructor 会指向错误的构造函数。
  • 覆盖 prototype 后忘记修复 constructor — 这是经典 bug。Person.prototype = {} 之后,p.constructor 变成 Object 而不是 Person。
  • 箭头函数没有 prototype — 箭头函数不能作为构造函数,没有 prototype 属性。
创建于 2026/3/15 更新于 2026/7/15
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本