这是我参与「第四届青训营 」笔记创作活动的的第4天
如何写好JavaScript(上)
一、写好JS的一些原则
- 各司其责:让HTML、CSS和JavaScript职能分离。
- 组件封装:好的UI组件具备正确性、扩展性、复用性。
- 过程抽象:应用函数式编程思想。
二、各司其责
❓:写一段JS,控制一个网页,让它支持浅色和深色两种浏览模式。 如果是你来实现,你会怎么做?
版本一
码上掘金 (juejin.cn) 版本一由JS直接地去操纵样式,让JS做了CSS应该做的事,没有做到职能分离,各司其责。
版本二
码上掘金 (juejin.cn)
版本二在CSS中定义class,仅通过className来操纵html元素的状态,符合各司其责的原则。
版本三
码上掘金 (juejin.cn)
版本三通过for将Label和CheckBox联系起来,再将CheckBox隐藏起来,实现了零JS完成相同功能。
总结
- HTML/CSS/JS 各司其责
- 应当避免不必要的由 JS 直接操作样式
- 可以用 class 来表示状态
- 纯展示类交互寻求零 JS 方案
三、组件封装
组件是指Web页面上抽出来一个个包含模板(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性。
❓:用原生 JS 写一个电商网站的轮播图,应该怎么实现?
结构:HTML
<div id="my-slider" class="slider-list">
<ul>
<li class="slider-list__item--selected">
<img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png">
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg">
</li>
<li class="slider-list__item">
<img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg">
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg">
</li>
</ul>
</div>
轮播图是一个典型的列表结构,我们可以使用无序列表ul元素来实现。
表现:CSS
#my-slider{
position: relative;
width: 790px;
}
.slider-list ul{
list-style-type:none;
position: relative;
padding: 0;
margin: 0;
}
.slider-list__item,
.slider-list__item--selected{
position: absolute;
transition: opacity 1s;
opacity: 0;
text-align: center;
}
.slider-list__item--selected{
transition: opacity 1s;
opacity: 1;
}
- 使用 CSS 绝对定位将图片重叠在同一个位置
- 轮播图切换的状态使用修饰符(modifier)
- 轮播图的切换动画使用 CSS transition
行为:JS
行为:API
行为:控制流
使用自定义事件来解耦。 码上掘金 (juejin.cn)
总结:基本方法
- 结构设计
- 展现效果
- 行为设计
- API(功能)
- Event(控制流)
重构:插件化
- 将控制元素抽取成插件
- 插件与组件之间通过依赖注入方式建立联系 码上掘金 (juejin.cn)
重构:模块化
- 将HTML模板化,更易于扩展
码上掘金 (juejin.cn)
组件框架
- 将组件通用模型抽象出来
码上掘金 (juejin.cn)
总结
- 组件设计的原则:封装性、正确性、扩展性、复用性
- 实现组件的步骤:结构设计、展现效果、行为设计
- 三次重构
- 插件化
- 模板化
- 抽象化(组件框架)
四、过程抽象
- 用来处理局部细节控制的一些方法
- 函数式编程思想的基础应用
高阶函数(HOF)
高阶函数是什么?
- 以函数作为参数
- 以函数作为返回值
- 常用于作为函数装饰器
常用高阶函数
- Once 👆 Once
- Throttle 👆 Throttle
- Debounce 👆 Debounce
- Consumer码上掘金 (juejin.cn) 👆 Consumer
- Iterative 👆 Interative
为什么要使用高阶函数?
- 在一个库中,我们应该尽可能使用纯函数,减少非纯函数,从而提升库的可维护性。
- 使用高阶函数可以大减少我们使用非纯函数的可能性
编程范式
命令式与声明式
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);
👆 声明式
例子
- Toggle - 命令式 👆Toggle - 命令式
- Toggle - 声明式 👆Toggle - 声明式
- Toggle - 三态
👆Toggle - 三态
总结
-
过程抽象 / HOF / 装饰器
-
命令式 / 声明式