跟着月影学JavaScript | 青训营笔记

72 阅读3分钟

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

一、本堂课重点内容:

本节课从实践维度解读在实际编码过程中何种类型的 JavaScript 代码称之为“好代码”,并从 JS 出发,总结其他语言编码可遵循的共性原则,由浅入深,该小节将集中讲解三大原则:各司其职、组件封装、过程抽象。

二、详细知识点介绍:

各司其职

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

组件封装

组件是指Web页面抽出来一个个包含模板(HTML)、功能(JS)和样式(CSS)的单元。

  • 组件设计原则:
    • 封装性
    • 正确性
    • 扩展性
    • 复用性
  • 实现组件的步骤
    • 结构设计
    • 展现效果
    • 行为设计
  • 三次重构
    • 插件化:插件化是为了解耦,将控制元素抽取成插件,插件与组件之间通过依赖注入的方式建立联系
    • 模板化:将HTML模板化,更易于扩展
    • 抽象化:将通用的组件模型抽象出来,便于复用

过程抽象

  • 用来处理一些局部细节控制的一些方法
  • 函数编程思想的基础应用

三、实践练习例子:

各司其职

深夜食堂,即将阅读页面在白天和黑夜模式切换的例子。

  • 我们可以用JS(如下),用JS直接操作页面样式的状态切换。
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
  const body = document.body;
  if(e.target.innerHTML === '🌞') {
    body.style.backgroundColor = 'black';
    body.style.color = 'white';
    e.target.innerHTML = '🌜';
  } else {
    body.style.backgroundColor = 'white';
    body.style.color = 'black';
    e.target.innerHTML = '🌞';
  }
});
  • 也可以通过CSS的状态选择器来操作,零JS代码

  <input id="modeCheckBox" type="checkbox">
  <div class="content">
    <header>
      <label id="modeBtn" for="modeCheckBox"></label>
      .........
/*CSS*/
#modeCheckBox {
  display: none;
}

#modeCheckBox:checked + .content {
  background-color: black;
  color: white;
  transition: all 1s;
}

#modeBtn {
  font-size: 2rem;
  float: right;
}

#modeBtn::after {
  content: '🌞';
}

#modeCheckBox:checked + .content #modeBtn::after {
  content: '🌜';
  • 两者比较而言,后者更好,后者通过表单间接操作样式切换,更为符合“各司其职”,减少损耗,提高效率。

过程抽象

  • 我们通常会对短时间内的操作次数进行限制,而这个需求是在多个场景都需要的,为了能够让“短时间内的重复操作只执行一次”的需求覆盖不同的时间处理,我们需要将这个需求剥离出来。而这个过程我们称为过程抽象
  • 我们常用的高阶函数就是对上面的定义的运用,如上面情况对于高阶函数once,节流函数(throttle)也是其中一种,可以参考下面
function throttle(fn, time = 500){
  let timer;
  return function(...args){
    if(timer == null){
      fn.apply(this,  args);
      timer = setTimeout(() => {
        timer = null;
      }, time)
    }
  }
}

btn.onclick = throttle(function(e){
  circle.innerHTML = parseInt(circle.innerHTML) + 1;
  circle.className = 'fade';
  setTimeout(() => circle.className = '', 250);
});
  • 通过高阶函数节流的展示,我们可以总结一下高阶函数的特征
    • 以函数作为参数
    • 以函数作为返回值
    • 常用于作为函数的装饰器

四、课后个人总结:

百尺高楼从地面开始,我个人的JS基础不足以完全消化这堂课的内容,稍后要补充一下。