如何写好JavaScript | 青训营笔记

79 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第3天

JS基础:看犀牛书+红宝书。

一. 写好JS的原则

  1. 各司其职:HTML、CSS、JavaScript职能分离。
  2. 组件封装:好的UI组件具备正确性、扩展性、复用性。
  3. 过程抽象:应用函数式编程思想。

1. 各司其职

举例

写一段JS控制网页支持深色和浅色模式。

版本一:直接操作style。

做法: 设置切换颜色模式的按钮 ,通过按钮点击事件判断当前颜色模式 并 修改按钮文字和页面样式为另一个模式。

不足: 修改了页面结构,越权控制CSS样式;可读性差,难以理解代码本身含义。

版本二:操作class名字。

做法: 对两种模式设置两种样式,利用js切换class类名。

不足: 虽然只是通过js控制了类名,但仍然属于利用js控制样式。

版本三:使用CSS伪类选择器匹配元素状态。

做法: 通过设置label for="checkbox" ,实现点击label与点击checkbox触发相同事件。

优点: 实现了零 JS 方案。

结论

  • HTML/CSS/JS 各司其责。
  • 应当避免不必要的由 JS 直接操作样式。
  • 可以用 class 来表示状态。
  • 纯展示类交互寻求零 JS 方案(但不强求)。

2. 组件封装

举例

用原生JS写一个轮播图。

  1. 结构。
  • 可以使用无序列表ul元素来实现。
  1. 表现。
  • 使用 CSS 绝对定位将图片重叠在同一个位置;

  • 轮播图切换的状态使用修饰符(modifier);

  • 轮播图的切换动画使用 CSS transition。

  1. 行为。
  • API:getSelectItem()获取选中元素,getSelectItemIndex()获取选中元素的序号,slideTo()切换到第n个场景,slideNext()切换到后一场景,slidePrev()切换到前一场景。
  • 控制流:使用自定义事件来解耦。mouseover()鼠标移入,mouseout()鼠标离开。监听自定义slide()
  1. 当前结论。
  • 结构设计
  • 展现效果
  • 行为设计:API功能,Event控制流。

重构

  1. 插件化:解耦,将控制元素抽取成插件,插件与组件之间通过依赖注入方式建立联系。

  2. 模板化:解耦,将HTML模板化,更易于扩展。

  3. 抽象化(组件框架):抽象,将组件通用模型抽象出来。

组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性。

总结

  • 组件设计的原则:封装性、正确性、扩展性、复用性。
  • 实现组件的步骤:结构设计、展现效果、行为设计。
  • 三次重构:插件化、模板化、抽象化(组件框架)。

3. 过程抽象

  • 用来处理局部细节控制的一些方法

  • 函数式编程思想的基础应用

举例

1. 操作次数限制

  • 一些异步交互

  • 一次性的HTTP请求

2. 高阶函数

  • Once函数:为了能够让“只执行一次“的需求覆盖不同的事件处理,我们可以将这个需求剥离出来。这个过程我们称为过程抽象。

  • HOF

    以函数作为参数

    以函数作为返回值

    常用于作为函数装饰器

  • 常用高阶函数

    Once

    Throttle

    Debounce

    Consumer / 2

    Iterative

  • 为什么要使用高阶函数?

    纯函数:没有副作用,可预期。不需要构建环境。

    非纯函数:有副作用。测试时需要提供外部环境,测试完需要销毁环境。

3. 编程范式

命令式:怎么做

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);

总结

  1. 过程抽象/HOF/装饰器
  2. 命令式/声明式