JavaScript框架底层依赖原型机制实现安全可控的功能扩展:Vue 2用getter/setter劫持属性访问并共享$set等方法,React Fiber通过原型共享协调逻辑,工具库用Object.create构建委托链,class语法糖下仍手动维护prototype链。

JavaScript 框架(如 Vue、React、Angular)底层大量依赖原型机制,但不直接暴露或鼓励用户操作 __proto__ 或重写 prototype。它们利用原型继承的底层能力,以安全、可控、可维护的方式扩展核心功能——本质是“用原型链实现方法共享与行为委托”,而非“靠修改原型动态打补丁”。
Vue 2 的响应式系统基于原型链做属性拦截代理
Vue 2 的 data 对象在初始化时,会通过 Object.defineProperty 在其原型链上(更准确地说:在观测后的对象自身或其访问器属性上)设置 getter/setter。虽然它没改 Object.prototype,但关键点在于:
- 响应式对象本身没有重写所有方法,而是把依赖收集、派发更新等逻辑封装在 getter/setter 中;
- 组件实例(
vm)的$data、$props等属性,其访问最终委托到响应式处理后的对象,而该对象的原型仍是Object.prototype——但它的属性访问已被“劫持”; -
Vue.prototype上挂载了$set、$delete、$watch等方法,所有组件实例都能继承使用,这是典型的原型方法共享。
React 的 Fiber 架构中,节点类型复用靠构造函数+原型链组织
React 16+ 的 FiberNode 是一个轻量构造函数,大量实例共用同一套原型方法:
-
FiberNode.prototype.return、.child、.sibling等字段虽是实例属性,但beginWork、completeWork等协调逻辑作为方法定义在FiberNode.prototype上; - 不同类型的 Fiber(如
HostComponent、FunctionComponent)并不各自定义一整套协调逻辑,而是通过tag字段区分行为,并在统一的原型方法中做条件分支; - 这种设计避免了为每个节点重复创建函数,节省内存,也符合原型链“共享行为、隔离状态”的初衷。
框架工具类(如 Lodash、Axios)广泛使用 Object.create 实现轻量继承
很多框架配套库或内部工具模块,用 Object.create 构建干净的原型委托链:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- Axios 的
create方法返回新实例,其原型指向一个预设配置 + 默认方法的对象,而不是拷贝全部逻辑; - Lodash 的
lodash/fp模块中,函数式变体常基于基础函数对象创建新对象,并通过Object.create(base)继承通用元信息(如placeholder、ary行为); - 这种方式绕过构造函数,不触发
constructor,只关心行为委托,更贴近原型本意。
ES6 class 是语法糖,但框架源码仍需手动修复 prototype 链
即使框架用 class 书写(如 Vue 3 的 ReactiveEffect 类),编译/构建后仍是原型操作。你能在源码里看到这类模式:
- 子类继承后,显式设置
SubClass.prototype.constructor = SubClass,防止因覆盖prototype导致 constructor 断连; - 某些性能敏感路径(如 diff 算法中的节点比对),会直接访问
instance.__proto__.someMethod或用Object.getPrototypeOf(instance).method.call(instance)显式调用,规避 this 绑定歧义; - 框架不会在运行时随意修改内置对象(如
Array.prototype)的原型,但会谨慎扩展自定义类的原型,比如给RenderContext添加slotted、attrs等只读访问器。
本质上,框架不是靠“魔改原型”来增强功能,而是把原型链当作一条受控的委托通道:数据响应走 getter 委托,节点调度走方法共享,实例能力走 prototype 注入。它不破坏原有结构,却让成千上万个对象高效复用同一份逻辑。

















