深入理解 JavaScript 中的原型与原型链

Last updated on August 26, 2025 pm

在 JavaScript 的世界里,原型和原型链是绕不开的核心概念,它们构建了 JS 独特的继承机制,也让许多开发者既好奇又头疼。今天我们就从几个关键角度,一起揭开它们的神秘面纱。

基于类与基于原型:两种不同的编程范式

在传统的面向对象编程语言中,比如 Java、C++,基于类(Class-based) 是主流的编程思想。在这种范式里,类就像是一个模具,它定义了对象所具有的属性和方法,而对象则是类的实例。我们必须先定义好类,然后通过new关键字来创建该类的对象,对象之间的关系是通过类的继承来确立的。

而 JavaScript 则不同,它采用的是基于原型(Prototype-based) 的编程范式。在这种模式下,并没有严格意义上的类的概念(虽然 ES6 引入了class语法,但这只是语法糖,底层依然是基于原型实现的)。对象可以直接从其他对象继承属性和方法,我们可以把原型看作是一个模板对象,新创建的对象会以这个模板为基础,共享它的属性和方法。

举个简单的例子,在基于类的编程中,我们先定义一个 “动物” 类,规定动物有 “名字” 属性和 “移动” 方法,然后 “猫” 类继承 “动物” 类,再创建 “猫” 类的实例。而在基于原型的 JavaScript 中,我们可以先创建一个 “动物” 对象作为原型,然后创建 “猫” 对象时,让它的原型指向 “动物” 对象,“猫” 对象就自然拥有了 “动物” 对象的属性和方法。

原型是啥,对象是如何产生的

原型(Prototype) 其实就是一个普通的对象,它是其他对象的模板,被用于共享属性和方法。在 JavaScript 中,每个对象(除了null和undefined)都有一个与之关联的原型对象。

那么对象是如何产生的呢?

当我们使用new关键字调用构造函数时,会创建一个新的对象。这个新对象的原型会指向构造函数的prototype属性所指向的对象。

例如,我们定义一个Person构造函数:

1
2
3
function Person(name) {
this.name = name;
}

当我们通过 new Person("张三") 创建一个对象时,这个新对象的原型就是 Person.prototype

此外,我们还可以使用 Object.create() 方法来创建对象,这个方法会以传入的对象为原型来创建新的对象。比如 Object.create(prototypeObj) 创建的新对象,其原型就是 prototypeObj。

原型链的用处

原型链(Prototype Chain) 是由对象的原型串联起来形成的链式结构。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 就会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(null)。

原型链的用处和好处主要有以下几点:

实现继承:这是原型链最主要的作用。通过原型链,一个对象可以继承多个原型对象的属性和方法,实现了代码的复用。比如,子对象的原型指向父对象,子对象就可以使用父对象的属性和方法,当父对象的原型又指向其他对象时,就形成了更长的继承链。

节省内存空间:由于多个对象可以共享同一个原型对象的属性和方法,不需要为每个对象都重复定义这些属性和方法,大大节省了内存。例如,所有通过同一个构造函数创建的对象,都会共享该构造函数prototype对象中的方法,而不是每个对象都拥有一份独立的方法副本。

动态扩展属性和方法:我们可以在原型对象上动态地添加属性和方法,这些添加的属性和方法会立即被所有依赖该原型的对象所共享。比如,给 Person.prototype 添加一个 sayHello 方法,那么所有通过 Person 构造函数创建的对象都能立即使用这个 sayHello 方法。

写在最后

原型和原型链是 JavaScript 实现面向对象编程的核心机制,理解它们对于掌握 JavaScript 有着至关重要的意义。

对于开发者而言,理解它们不仅是掌握 “继承”“内存优化” 等基础能力的关键,更是后续学习闭包、原型继承实战、甚至框架源码(如 Vue、React 中部分组件复用逻辑)的前提。


深入理解 JavaScript 中的原型与原型链
https://www.jvxiao.cn/posts/prototype-in-js.html
Author
jvxiao
Posted on
August 25, 2025
Licensed under