可复用组件的本质是副作用边界的管控。需明确区分创建/挂载/卸载三阶段,class 要手动管理生命周期与状态同步,函数式工厂适合轻量隔离场景,所有 DOM/异步操作必须配套清理,对外部环境读写须通过参数或返回值显式声明。

JavaScript 里没有原生的“组件”语法,所谓可复用组件,本质是封装行为与状态的模式选择问题。面向对象(class)和函数式(factory / hook 风格)都能实现,但适用场景和隐患差异很大——别一上来就写 class,也别迷信“纯函数无副作用”。
用 class 封装组件时,必须手动管理生命周期与状态同步
class 组件容易写出隐式依赖和内存泄漏,尤其在异步操作中。比如 DOM 挂载后发起请求,但组件已销毁,this 指向失效或更新挂起。
- 避免在
constructor或render中直接操作 DOM,改用connectedCallback(自定义元素)或显式init()方法 - 所有异步操作(
fetch、setTimeout、addEventListener)必须配套清理逻辑,例如保存AbortController.signal或在destroy()中移除监听器 -
this.state不要直接赋值,统一走this.setState({})并做浅合并,否则 React 式响应会失效(即使不用 React,状态变更通知也要可控)
函数式工厂函数更适合轻量、无状态或配置驱动的组件
工厂函数返回闭包,天然隔离作用域,适合生成多个独立实例,比如表单校验器、动画控制器、API 客户端实例。
function createCounter(initial = 0) {
let count = initial;
return {
inc: () => ++count,
dec: () => --count,
get: () => count,
reset: () => count = initial
};
}
const counter1 = createCounter(10);
const counter2 = createCounter(0);
console.log(counter1.inc()); // 11
console.log(counter2.get()); // 0
- 不依赖
this,无绑定风险;参数即契约,调用时明确传入依赖(如containerEl、apiBase) - 无法自动响应外部状态变化,适合“一次配置、长期运行”的场景;若需响应式,得额外接入信号(
Signal)或观察者 - 不能被
instanceof识别,调试时看不出类型——建议加Symbol.toStringTag或返回带type: 'Counter'的对象
DOM 组件必须明确区分“创建”“挂载”“卸载”三个阶段
无论 class 还是函数,只要涉及真实 DOM,就绕不开这三件事。漏掉卸载逻辑,事件监听器或定时器会持续存在,造成内存泄漏。
立即学习“Java免费学习笔记(深入)”;
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。《php中级教程之ajax技术》带你快速
- “创建”阶段只初始化数据和方法,不访问
document或window - “挂载”阶段接收容器节点(
el或shadowRoot),插入结构、绑定事件、启动轮询等 - “卸载”阶段必须:清除所有
addEventListener(用同一options对象)、调用controller.abort()、清除setTimeout/setInterval、解除 MutationObserver
一个典型错误是把挂载逻辑塞进构造函数,导致组件无法脱离 DOM 复用(比如 SSR 或测试环境)。
真正影响复用性的不是写法,而是副作用的可见范围
class 和函数式写法本身不决定可复用性,关键看副作用是否外溢。比如在组件内部修改全局 localStorage、重写 Date.prototype.format、或直接 document.body.classList.add(),都会让组件变成“黑盒炸弹”。
- 所有对外部环境的读写,都应通过参数传入或返回值暴露(如传入
storage对象而非硬编码localStorage) - 避免在组件内新建全局变量或监听
window级事件(除非明确设计为“全局守卫”) - 如果组件需要样式,优先用
CSSStyleSheet动态注入并标记id,卸载时可精准移除,而不是靠类名拼接或document.styleSheets遍历
可复用组件最难的部分,从来不是怎么写 class 或怎么写 factory,而是想清楚它该“知道什么”、又该“对谁负责”。边界模糊的地方,往往就是 bug 滋生的温床。










