JavaScript代码进阶(一)| 青训营笔记

129 阅读3分钟

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

如何写好JavaScript代码?(一)

  • 关于书籍:
    • 入门书籍:犀牛书 红宝书 (厚)
    • 进阶书籍:JS The Good Parts
  • 书籍知识经典,但未必新,因此可以有选择性地阅读

1 遵守原则

关于什么是“好”的JS代码?应该是更灵活的、更易于维护的、考虑更加全面的。如何实现这些目标呢?首先就是要遵守以下三个原则:

  • 各司其责:HTML、CSS和JavaScript分离
  • 组件封装:UI界面组件实现拓展与复用
  • 过程抽象:函数式编程

1.1 各司其责——结构、表现、行为分离

分离.png

  • 举例需求:点击按钮,实现网页夜间模式效果。
  • 版本1:用js控制css,代码表示含义不清晰,且当样式需求更改时,修改麻烦。
<script>
    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 = '🌞';
      }
    });
</script>
  • 版本2:在css中添加class控制样式更改,js控制行为变换,代码清晰,维护容易。
<script>
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
  const body = document.body;
  if(body.className !== 'night') {
    body.className = 'night';
  } else {
    body.className = '';
  }
});

</script>
  • 版本3:由于js只控制了样式变化,因此可以仅仅依赖css实现,避免js直接对样式的修改,彻底实现各司其责。
<body>
  <!-- 增加一个checkbox 控制变换content样式变化 -->
  <input id="modeCheckBox" type="checkbox">
  <div class="content">
    <header>
      <!-- 为label绑定checkbox事件 -->
      <label id="modeBtn" for="modeCheckBox"></label>
      <h1>深夜食堂</h1>
    </header>
  </div>
</body>
<style>
    /* 根据checkbox 选中状态 控制content的样式  实现夜间模式 */
    #modeCheckBox:checked + .content {
    background-color: black;
    color: white;
    transition: all 1s;
    }
    #modeCheckBox:checked + .content #modeBtn::after {
    content: '🌜';
    }
</style>

1.2 组件封装——正确性、拓展性、复用性

轮播图例子

轮播图例子.png

  • 结构-HTML
    • 无序列表 ul
  • 表现-CSS
    • 绝对定位 position
    • 修饰符 modifier
    • 切换动画 transition
  • 行为-JS
    • API——图片轮播功能
      • getSelectedItem()
      • getSelectedItemIndex()
      • slideTo()
      • slideNext()
      • slidePrevious()
    • 控制流——下方小圆点事件
      • 自定义事件:绑定对应顺序的小圆点与图片,实现解耦
改进
  • 插件化
    • 将控制元素抽取成插件
    • 插件与组件之间通过依赖注入建立联系
  • 模板化
    • 解耦:将HTML模板化,更易于扩展
    • 抽象:将组件通用模型抽象出来

1.3 过程抽象——高阶函数

  • 过程抽象:
    • 用来处理局部细节控制的一些方法
    • 将一些事件处理中共同的操作,比如“只响应一次”抽象出来,称为过程抽象
    • 可以通过高阶函数实现
  • 高阶函数:
    • 传参和返回值都是函数
    • 常用于作为函数装饰器
    • 常用高阶函数:
      • Once
      • Throttle
      • Debounce
      • Consumer/2
      • Iterative

高阶函数.png

  • 纯函数:输入A,输出B,每次调用结果相同,可维护性高,因此建议在库中多用高阶函数
  • 编程范式
    • 命令式——强调怎么做
      • 面向过程
      • 面型对象
    <script>
        let list = [1, 2, 3, 4];
        let mapl = [];
        for(let i = 0; i < list.length; i++) {
          mapl.push(list[i] * 2);
        }
    </script>
    
    • 声明式_——做什么
      • 逻辑式
      • 函数式
      • 具有更强的可扩展性
    <script>
        let list = [1, 2, 3, 4];
        const double = x => x * 2;
        list.map(double);
    </script>
    

编程范式.png

  • JS是复合型,兼容命令式和声明式风格,在代码编写时,可以考虑更多使用声明式,其更便于扩展和维护。

2 总结

  • 在了解JS基础语法的基础上,如何写“好”JS代码,尽量遵守下列原则:
    • 各司其责:HTML、CSS和JavaScript分离
    • 组件封装:UI界面组件实现拓展与复用
    • 过程抽象:函数式编程
  • 勤加练习,在实践中体会上述原则