JavaScript的面向对象基于原型链而非类,通过__proto__逐级查找属性和方法,最终止于Object.prototype;函数的prototype与实例的__proto__指向同一对象,实现共享行为的委托查找机制。

JavaScript 的面向对象不是靠“类”定义结构,而是靠对象之间直接链接形成的原型链来共享行为和数据。它不预设模板,而是让一个对象“有样学样”地继承另一个对象的属性和方法。
原型链的本质是一条查找路径
当你访问一个对象的属性或方法时,引擎会按顺序检查:
- 先看这个对象自己有没有该属性
- 没有就顺着 __proto__ 去它的原型对象上找
- 原型对象上也没有,就继续顺着它的 __proto__ 往上找
- 最终停在 Object.prototype,它的 __proto__ 是 null,链结束
这条从实例出发、逐级向上追溯的路线,就是原型链。它不是用来“复制”或“声明继承关系”的语法结构,而是一种运行时的属性查找机制。
函数的 prototype 和实例的 __proto__ 是一对钥匙
构造函数(比如 function Person() {})自带一个 prototype 属性,它是一个普通对象,专为未来创建的实例准备共享内容。
立即学习“Java免费学习笔记(深入)”;
用 new Person() 创建实例后,该实例会自动获得一个 __proto__ 属性,指向构造函数的 prototype 对象。
也就是说:
- Person.prototype 是“谁来提供共享内容”
- person.__proto__ 是“我往哪儿去找共享内容”
- 二者指向同一个对象,构成原型链的第一环
所有对象最终都连到 Object.prototype
哪怕你写 const obj = {},它也有原型链:
- obj.__proto__ === Object.prototype
- Object.prototype.__proto__ === null
所以像 toString()、hasOwnProperty() 这些通用方法,其实都来自 Object.prototype。你没定义它们,却能用,正是因为原型链帮你找到了。
继承不是“复制”,而是“委托查找”
JavaScript 中的继承不把父级属性搬进子级对象里,而是在需要时临时去上级原型中取。比如:
- 给 Person.prototype.sayHi = function(){}
- 多个 new Person() 实例都不存 sayHi,但都能调用
- 因为调用时,引擎沿原型链找到 Person.prototype 上的方法
这种设计节省内存,也支持运行时动态修改——改一次 prototype,所有实例立刻生效。


















