原型和原型链是什么?

0 阅读2分钟

一句话理解

原型(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.prototypeObject.prototypenull

验证:

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 的构造体系是循环结构。