1. 原型(prototype)是什么?
在 JS 里,每个函数都有一个特殊的属性 —— prototype。
当你通过构造函数 new 出来一个对象时,这个对象会自动拥有一个 隐藏属性 _ _ proto_ _,指向构造函数的 prototype。
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function () {
console.log(`Hi, I am ${this.name}`);
};
let p1 = new Person("淇淇");
p1.sayHi(); // Hi, I am 淇淇
console.log(p1.__proto__ === Person.prototype); // true
-
Person.prototype 是构造函数的原型对象。
-
p1._ _ proto_ _ 指向 Person.prototype。
2. 什么是原型链?
当我们访问一个对象的属性或方法时,如果对象本身没有这个属性,JavaScript 就会顺着 _ _ proto_ _ 一层一层往上找,直到找到 Object.prototype,再到 null 停止。
这一条“查找路径”就叫 原型链。
console.log(p1.toString());
流程是:
-
JS 先看 p1 自己有没有 toString。
-
没有,就去 p1._ _ proto_ _ = Person.prototype 找。
-
Person.prototype 里也没有,就去 Person.prototype._ _ proto_ _ 找。
-
这时指向 Object.prototype,找到了 toString。
-
如果还没有,就到 null,返回 undefined。
3. Function
在 JS 里:
- 所有函数(包括自定义的、内置的)都是由 Function 构造出来的。
function foo() {}
console.log(foo.__proto__ === Function.prototype); // true
- Function 自己也是一个函数,所以它本身也是由 Function 构造出来的(有点自指)。
console.log(Function.__proto__ === Function.prototype); // true
- Function.prototype 本身是一个函数对象,但它没有 prototype 属性(因为只有“构造函数对象”才有 prototype)。
- 所有函数的 .prototype._ _ proto_ _ 指向 Object.prototype,因为函数也是对象。
4. 链条梳理
我们看一下最重要的几条原型链:
- 普通函数
function foo() {}
foo.__proto__ === Function.prototype; // ✅
foo.prototype.__proto__ === Object.prototype; // ✅
- Function 自己
Function.__proto__ === Function.prototype; // ✅ 自指关系
- 顶层 Object
Object.__proto__ === Function.prototype; // ✅ Object 也是函数
Object.prototype.__proto__ === null; // ✅ 原型链终点
5. 完整链条图示
6. 核心规律
-
实例对象的 _ _ proto_ _ → 构造函数的 prototype。
-
构造函数是函数,所以它的 _ _ proto_ _ → Function.prototype。
-
函数本身是对象,所以它的 prototype._ _ proto_ _ → Object.prototype。
-
原型链的终点是 Object.prototype._ _ proto_ _ = null。
7. 一句话总结
原型链就是对象属性的查找机制:
当对象本身没有这个属性时,会沿着 _ _ proto_ _ 链条往上查找,直到 Object.prototype 或 null 为止。