如何用javascript创建可复用的组件_面向对象与函数式编程的思路【教程】

10次阅读

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

如何用javascript创建可复用的组件_面向对象与函数式编程的思路【教程】

javaScript 里没有原生的“组件”语法,所谓可复用组件,本质是封装行为与状态的模式选择问题。面向对象(class)和函数式(factory / hook 风格)都能实现,但适用场景和隐患差异很大——别一上来就写 class,也别迷信“纯函数无副作用”。

用 class 封装组件时,必须手动管理生命周期与状态同步

class 组件容易写出隐式依赖和内存泄漏,尤其在异步操作中。比如 DOM 挂载后发起请求,但组件已销毁,this 指向失效或更新挂起。

  • 避免在 constructorrender 中直接操作 DOM,改用 connectedCallback(自定义元素)或显式 init() 方法
  • 所有异步操作(fetchsetTimeoutaddEventListener)必须配套清理逻辑,例如保存 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,无绑定风险;参数即契约,调用时明确传入依赖(如 containerElapiBase
  • 无法自动响应外部状态变化,适合“一次配置、长期运行”的场景;若需响应式,得额外接入信号(Signal)或观察者
  • 不能被 instanceof 识别,调试时看不出类型——建议加 symbol.toStringTag 或返回带 type: 'Counter' 的对象

DOM 组件必须明确区分“创建”“挂载”“卸载”三个阶段

无论 class 还是函数,只要涉及真实 DOM,就绕不开这三件事。漏掉卸载逻辑,事件监听器或定时器会持续存在,造成内存泄漏。

立即学习Java免费学习笔记(深入)”;

  • “创建”阶段只初始化数据和方法,不访问 documentwindow
  • “挂载”阶段接收容器节点(elshadowRoot),插入结构、绑定事件、启动轮询等
  • “卸载”阶段必须:清除所有 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 滋生的温床。

text=ZqhQzanResources