JavaScript面向对象基于原型链而非类,通过__proto__指针实现单向委托查找,终点为Object.prototype.__proto__ === null;prototype是函数独有的共享模板,__proto__是对象的查找入口,constructor用于反向定位构造函数;ES6 class仅为语法糖,底层仍依赖原型机制。

JavaScript 面向对象不是靠“类”定义关系,而是靠对象间共享内存 + 委托查找来运转。原型链的本质,是一条由 __proto__ 指针串起的、自下而上的属性访问路径,终点固定为 Object.prototype.__proto__ === null。
原型存在的根本目的:节省内存,实现方法复用
JS 不在每个实例上重复存一份相同方法。构造函数的 prototype 是一块独立堆内存区域,所有实例通过 __proto__ 共同引用它。比如:
-
this.name = name→ 存在实例自身内存中,彼此隔离 -
Person.prototype.say = function(){...}→ 只存一份,在Person.prototype对象里 - 100 个
new Person()实例,共用同一个say函数,不占 100 份空间
三个关键角色必须分清
prototype:仅函数拥有,是“共享模板”的地址。声明 function Foo(){} 时,V8 就已为其分配好这块原型内存。
__proto__:每个对象(包括函数、数组、实例)都有,是“查找入口”。它指向该对象的原型对象,即其构造函数的 prototype。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
constructor:存在于每个 prototype 对象上,值为对应构造函数本身,用于反向定位“我是谁造出来的”。
三者关系可简化为:
实例.__proto__ === 构造函数.prototype
构造函数.prototype.constructor === 构造函数
原型链的查找过程:单向委托,逐级向上
访问 obj.method() 时,引擎执行严格线性查找:
- 先查
obj自身是否有method - 没有?查
obj.__proto__(即构造函数.prototype) - 还没有?查
obj.__proto__.__proto__(通常是Object.prototype) - 再没有?查
Object.prototype.__proto__→ 结果是null,查找终止,返回undefined
这个链条不可逆、不跳转、不并行——只有一条路,且每步都是指针引用,不是拷贝。
ES6 class 并未改变底层机制
class Person{ constructor(n){this.name=n;} say(){} } 看似面向类,但编译后仍是函数 + prototype 操作:
-
Person本质是函数,有Person.prototype -
say方法被挂载到Person.prototype上 -
new Person()实例的__proto__依然指向它 - 继承写法
class Dog extends Animal,底层仍是Dog.prototype.__proto__ = Animal.prototype
class 是语法糖,原型链才是运行时真实结构。


















