一句话理解
原型(prototype)是对象的共享属性仓库。
原型链(prototype chain)是对象查找属性的一条向上查找的链路。
一、先理解一个核心问题
JS 为什么可以这样?
const arr = [1, 2, 3]
arr.push(4)
arr.toString()
arr.map(x => x * 2)
你有没有给 arr 定义 push?
没有。
那 push 从哪来的?
答案:
来自 Array 的原型。
二、什么是原型(prototype)?
在 JavaScript 里:
每个函数都有一个 prototype 属性
每个对象都有一个 proto 指针
1️⃣ 函数的 prototype
function Person() {}
console.log(Person.prototype)
输出是一个对象:
{
constructor: Person
}
这个 prototype 就是:
未来通过 new 创建的实例共享的属性对象
2️⃣ 实例的 proto
function Person() {}
const p = new Person()
console.log(p.__proto__ === Person.prototype) // true
关系是:
p.__proto__ → Person.prototype
也就是说:
实例通过 proto 指向构造函数的 prototype
三、什么是原型链?
当你访问一个属性时:
p.name
JS 查找顺序:
1️⃣ 先查 p 自身
2️⃣ 没有 → 查 p.__proto__
3️⃣ 还没有 → 查 p.__proto__.__proto__
4️⃣ 一直到 null
这条查找路径:
就叫原型链
四、完整链路结构图
实例对象 p
↓
Person.prototype
↓
Object.prototype
↓
null
验证:
console.log(p.__proto__ === Person.prototype) // true
console.log(Person.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__) // null
五、为什么要有原型?
为了节省内存。
看对比:
❌ 错误方式:
function Person() {
this.say = function () {
console.log("hi")
}
}
每 new 一个对象:
都创建一个新的 say 函数
浪费内存。
✅ 正确方式:
function Person() {}
Person.prototype.say = function () {
console.log("hi")
}
所有实例共享同一个 say。
六、重要知识点整理(面试常问)
1️⃣ prototype 和 proto 区别
| 名字 | 属于谁 | 作用 |
|---|---|---|
| prototype | 函数 | 存放共享属性 |
| proto | 对象 | 指向构造函数的 prototype |
2️⃣ constructor 是什么?
Person.prototype.constructor === Person
作用:
记录这个原型属于哪个构造函数
3️⃣ instanceof 原理
p instanceof Person
本质:
检查 Person.prototype 是否在 p 的原型链上
等价逻辑:
function myInstanceof(obj, constructor) {
let proto = obj.__proto__
while (proto) {
if (proto === constructor.prototype) return true
proto = proto.__proto__
}
return false
}
七、类(class)本质也是原型
class Person {
say() {
console.log("hi")
}
}
本质等价于:
function Person() {}
Person.prototype.say = function () {
console.log("hi")
}
class 只是语法糖。
八、面试标准回答模板(高级版)
你可以这样回答:
在 JavaScript 中,每个函数都有一个 prototype 属性,这个对象用于存放实例共享的属性和方法。
通过 new 创建的实例对象内部有一个隐式属性 [[Prototype]](通常可以通过 proto 访问),它指向构造函数的 prototype。
当我们访问对象属性时,如果当前对象上没有该属性,JavaScript 会沿着原型链向上查找,直到 Object.prototype 或 null 为止。
这种机制叫做原型链。
原型机制的核心目的是实现属性共享和内存复用,同时也是 JavaScript 实现继承的基础。
九、你这个水平必须知道的底层点
1️⃣ 所有对象最终都继承自 Object.prototype
({}).__proto__ === Object.prototype
2️⃣ Function 也是对象
Function.__proto__ === Function.prototype
JS 是一个自举结构。
3️⃣ Object 也是函数
Object instanceof Function // true
JS 的构造体系是循环结构。