这是我参与「第五届青训营」伴学笔记创作活动的第 2 天
本堂课重点内容
本节课重点讲述了JavaScript的编码三大原则:各司其职、组件封装、过程抽象及各自应用。
JavaScript的编码原则之各司其职
案例:深夜食堂——通过开关控制白天/黑夜背景颜色主题切换
- 版本1——通过DOM操作直接改变元素的style属性
- 版本2——通过DOM操作控制元素类名的变化(常用)
- 版本3——无JS操作版本,通过改变checkbox的checked状态属性来改变元素的样式
<input id="modeCheckBox" type="checkbox">(这个隐藏)
<div class="content">
<label id="modeBtn" for="modeCheckBox">切换按钮</label>
<!-- 这个切换就能够切换复选框状态 -->
</div>
#modeCheckBox{
display:none;
}
#modeCheckBox:checked + .content{
background-color:black;
color:white;
}
案例结论:
- HTML/CSS/JS各司其责
- 应当避免不必要的由JS直接操作样式
- 可以用class来表示状态
- 纯展示类交互寻求零JS方案
JavaScript的编码原则之组件封装
案例:轮播图组件
步骤:
- 使用CSS动画:使用绝对定位把图片堆叠在一起,再使用CSS动画设置图片切换效果
- 定义Slider类
- getSelectItem() 获取当前元素
- getSelectedItemIndex() 获取当前元素索引
- slideTo() 滑到某一张
- slideNext() 滑到下一张
- slidePrevious() 滑到上一张
案例结论——组件封装的基本方法:
- 结构设计
- 展现效果
- 行为设计(API-功能,Event-控制流 )
重构轮播图组件
1.重构之插件化
将控制元素单独提取出来组成插件;插件与组件之间通过“依赖注入”方式建立联系
2.重构之模板化
将HTML模板化,更容易扩展。即定义一个类,使用render函数返回标签组合模板。
3.重构之抽象化
将组件的通用模型给抽象出来。
组件封装案例结论:
- 设计原则:封装性、正确性、扩展性、复用性
- 实现组件的步骤:结构设计、展现效果、行为设计
- 三次重构:插件化、模板化、抽象化(组件框架)
改进空间:把插件和组件组合,可以有父子嵌套
JavaScript的编码原则之过程抽象
过程抽象
过程抽象是指用来处理局部细节控制的一些方法,是函数式编程思想的基础应用。
案例:实现次数控制功能
高阶函数 Once-“只执行一次”
function once(fn){
return function(...args){
if(fn){
const ret = fn.apply(this,args);
fn = null;
return ret;
}
}
}
将类似于“只执行一次”这种需求从事件处理中剥离出来,这个过程就叫过程抽象。
高阶函数
高阶函数(HOF):以函数为参数、函数为返回值;常用作为函数装饰器,如:
function HOF0(fn){//认为参数fn与函数HOF0是等价的
return function(...args){return fn.apply(this,args);}
}
常用的高阶函数:
- Once 只执行一次
- Throttle 节流函数
- Debounce 防抖函数(案例:小鸟跟随鼠标)
- Consumer 延时调用
- Iterative 迭代器,用于重复操作
为什么要使用高阶函数?
首先了解什么是纯函数?
一个函数的返回结果只依赖于它的参数 函数在执行过程里面没有任何副作用(不会造成外部变量的改变)
纯函数的优点:
- 结果可预期的:一个固定的输入肯定会得出固定的输出
- 没有副作用:不会对外部产生任何的影响
- 测试方便
- 使用纯函数可以提高库的可维护性
由于高阶函数也是纯函数,所以它具备纯函数的优点。
编程范式
声明式与命令式: 声明式代码更简洁,具有更强的可扩展性。声明式-怎么做,命令式-做什么。
案例:
- 命令式:
switcher.onclick = function(evt){
if(evt.target.className==='on'){evt.target.className='off'}
else{evt.target.className='on'}
}
- 声明式:
function toggle(...actions){
return function(...args){
let action = actions.shift();
actions.push(action);
return action.apply(this,args);
}
}
switcher.onclick = toggle{
evt => evt.target.className='off'
evt => evt.target.className='on'
}
个人总结
通过案例代码的层层递进、一步步剖析,逐渐理解了代码优化的妙处。在以后的编码中,我也要逐渐养成优秀的编码思想,勤加练习。
参考文章
简单解读高阶函数和纯函数 https://juejin.cn/post/6844903769444974606