原型链的本质是对象内部[[Prototype]]隐式引用构成的、逐级向上直至null的链式结构。它通过属性查找机制实现继承:先查自身,再沿链向上,直到找到属性或返回undefined,从而共享方法节省内存。

JavaScript中的原型链是对象之间建立继承关系的核心机制,它让一个对象可以访问另一个对象的属性和方法。
原型链的本质是什么?
每个JavaScript对象内部都有一个隐式引用([[Prototype]]),指向它的原型对象。这个原型对象本身也有自己的原型,层层向上,直到最终指向null——这就是原型链。你可以用Object.getPrototypeOf(obj)或obj.__proto__(不推荐)查看对象的原型。
函数对象还有prototype属性,它是一个普通对象,会被赋值给该函数创建的实例的[[Prototype]]。例如:
-
function Person() {}定义后,Person.prototype就是将来所有new Person()实例的原型 -
const p = new Person()→p.[[Prototype]] === Person.prototype -
Person.prototype.[[Prototype]] === Object.prototype→Object.prototype.[[Prototype]] === null
原型链如何实现继承?
当访问一个对象的属性时,JavaScript引擎会按以下顺序查找:
立即学习“Java免费学习笔记(深入)”;
- 先在对象自身查找
- 没找到,就沿着
[[Prototype]]链向上查找,依次检查每个原型对象 - 直到找到该属性,或到达链尾(
null)返回undefined
这使得子对象“继承”了原型上的方法和属性,无需复制,节省内存。比如:
Array.prototype.map存在于所有数组实例的原型链上,所以[1,2].map(x => x*2)能直接调用,尽管数组字面量本身没有map属性。
常见的继承写法与原型链关系
ES6之前常用“组合继承”或“寄生组合继承”,核心都是手动设置子类原型的[[Prototype]]指向父类原型:
-
Child.prototype = Object.create(Parent.prototype)—— 让Child实例的原型链能访问Parent.prototype上的方法 - 再补回
constructor:Child.prototype.constructor = Child - ES6的
class和extends本质也是基于这套原型链机制,只是语法糖
注意:Object.create(null)创建的对象没有原型,其原型链只有一层null,无法继承任何内置方法(如toString)。
原型链不是万能的
它只支持单向、动态的属性查找,不提供真正的“类式封装”:
- 无法限制属性访问(无private关键字,直到ES2022的
#field私有字段) - 修改原型会影响所有继承它的实例(包括已创建的)
- 不能直接获取某对象“继承自谁”,只能查它的直接原型
现代开发中,原型链仍是底层基础,但日常更多通过class、extends、super等语法使用,背后逻辑不变。










