如何写好 JavaScript
👀 什么才是好的 JavaScript 代码?
Q:什么是 ECMA?
A:📦 ECMAScript(简称ES),它定义了JavaScript的核心规范。ECMAScript规范规定了JavaScript的语法、类型、语义和API,使不同的JavaScript引擎能够相互兼容。
📚 各司其职
让 HTML、CSS 和 JavaScript 职能分离。
例如,写一段 JS,控制一个网页支持浅色和深色两种浏览模式,你会怎么做 🤔?
- 🔴 初学者(爱好者)可能会直接使用 JS 操作 DOM,判断状态后使用 JS 修改对应元素的样式。
- 🟡 升级版(工程师)可以选择控制对应元素的 class,以修改样式,这种方法更加简洁,同时有效分隔了 JS 和 CSS 的职能,提高了可读性,也便于后期的维护。
- 🟢 再升级,可以仅使用 CSS 来实现颜色主题切换(伪类选择器),避免使用 JS 对样式进行操作,进一步提升了可读性。
小节:
- 🔕 避免不必要的 JS 操作样式
- 🧰 使用 class 来表示状态
- 🔮 纯展示类交互寻求零 JS 方案
📦 组件封装
组件是指 Web 页面上抽出来一个个包含模板(HTML)、功能(JS)和样式(CSS)的单元,好的 UI 组件具有正确性、拓展型和复用性。
基本思路
例如:用原生 JS 写一个电商网站的轮播图,应该如何实现?
-
💪 结构(HTML)
典型的无序列表结构,使用
- 来实现。
-
🪭 表现(CSS)
- 使用CSS绝对定位将图片重叠在一个位置
- 轮播图切换的状态使用修饰符(modlfier)
- 轮播图的切换动画使用 CSS transition
-
🤖 行为(JavaScript)
- API
- 控制流:使用自定义时间来解耦
总结:
-
⚙️ 结构设计
-
💎 展现效果
-
🦾 行为设计
- API(功能)
- Event(控制流)
重构:插件化
插件化就是解耦的过程:
- 插件化:将控制元素抽取成插件
- 插件与组件之间通过依赖注入的方式建立联系
- 模板化:将 HTML 模板化,更易于拓展(参照一些成熟的 JS 框架)
- 抽象化:将组件通用模型抽象出来
💢 记住,
各司其职 != 不同代码分开写!永不停止的思考 🤔:有没有进一步优化空间?
🧸 过程抽象
应用函数式编程思想。
🪝 React Hooks 是一种典型的过程抽象。
- 用来处理局部细节控制的一些方法
- 函数式编程思想的基础应用
基本思路
例如:现在有一个简单的 TodoList 功能,存在条件竞争问题,应该如何修复 🤔?
高阶函数:once
function once(fn) { return function(...args) { if (fn) { const ret = fn.apply(this.args); fn = null; return ret; } } }为了能够让“只执行一次”的需求覆盖不同的时间处理,我们可以将这个需求剥离出来。这个过程我们成为过程抽象。
🎁 高阶函数 HOF
- 以函数为参数
- 以函数为返回值
- 常用于作为函数装饰器
常用的高阶函数:
- once:单次触发
- throttle:节流
- debouncd:防抖
- consumer:同步操作转化为异步
- lterative(JQuery 时代的产物)
我们为什么要使用高阶函数 🤔?这需要我们先了解一下纯函数。
💎 纯函数的特点是:
- 无副作用
- 与外部状态、调用次数等均无关
- 结果可预期,输入一定则输出一定
在我们的库中,应该尽可能的使用纯函数,这样可以提高可维护性。
编程范式
命令式与声明式。
// 命令式,注重怎么做 let list = [1, 2, 3, 4]; let mapl = []; for(let i = 0; i < list.length; i++) { mapl.push(list[i] * 2); } // 声明式,注重做什么,相对简洁,具有更强的可拓展性 let list = [1, 2, 3, 4]; const double = x => x * 2; list.map(double);总结:
- 过程抽象 / HOF / 装饰器
- 命令式 / 声明式
-