原型模式是JavaScript原生机制,需合理区分共享(prototype)与独立(实例)属性;方法应统一挂载prototype以节省内存并保证相等性;Object.create适用于配置对象克隆;框架如Vue/React通过原型链或闭包实现能力复用;须警惕原型污染与可变对象共享陷阱。

原型模式在 JavaScript 中不是“选配”,而是语言原生机制——它天然存在,关键在于是否被有意识地用对、用稳。
核心落地逻辑就一条:把该共享的放原型上,把该独立的放实例里。
避免方法重复创建,统一挂到 prototype
函数是典型的可共享资源。每次 new 一个实例都新建一份方法,既浪费内存,又破坏相等性判断。
function Button(text) {
this.text = text; // ✅ 每个按钮文本不同,放实例
}
// ✅ 方法共享:所有按钮共用同一份逻辑
Button.prototype.render = function(container) {
const el = document.createElement('button');
el.textContent = this.text;
container.appendChild(el);
return el;
};
Button.prototype.click = function(handler) {
this.element?.addEventListener('click', handler);
};这样创建 100 个按钮,render 函数只有一份,内存更省,btn1.render === btn2.render 也为 true,便于测试和调试。
立即学习“Java免费学习笔记(深入)”;
用 Object.create 显式克隆,适合配置型对象
当对象结构固定、属性多变、无需构造函数时,Object.create 是最轻量、最直观的原型模式落地方式:
const modalConfig = {
width: '400px',
height: '300px',
closable: true,
onOpen() { console.log('模态框已打开'); }
};
const loginModal = Object.create(modalConfig);
loginModal.width = '500px'; // ✅ 覆盖自有属性
loginModal.title = '登录'; // ✅ 添加新属性(不影响原型)
const alertModal = Object.create(modalConfig);
alertModal.closable = false; // ✅ 独立状态,互不干扰这种方式跳过构造函数,直接基于模板对象生成实例,特别适合主题配置、组件默认 props、API 请求模板等场景。
Vue/React 中的“挂载式”原型应用
框架层早已将原型模式用得非常自然:
- Vue 2 中
Vue.prototype.$http = axios,让所有组件实例都能访问$http; - Vue 3 的
app.config.globalProperties.$bus = mitt(),本质也是往根原型链注入能力; - React 的自定义 Hook 虽不叫 prototype,但
useEffect、useState等内部依赖闭包 + 模块级作用域,实现的同样是“一次定义、处处复用”的效果——思想同源。
这类做法的本质,就是把通用能力“种”在原型链上游,下游实例自动继承,不用每个组件手动 import 或传 prop。
警惕原型污染与属性遮蔽陷阱
原型模式强大,但误用会引发隐蔽问题:
- ❌ 不要在
Object.prototype上添加属性(如Object.prototype.toJSON = ...),会污染全局,导致for...in循环异常; - ❌ 避免在原型上放可变对象(如
prototype.cache = {}),否则所有实例共享同一个对象引用,互相干扰; - ✅ 实例初始化时,优先用
this.xxx = xxx初始化独有状态; - ✅ 若需默认值,可在实例方法中惰性初始化:
get cache() { if (!this._cache) this._cache = {}; return this._cache; }
不复杂但容易忽略。


















