如何写好JavaScript(下) | 青训营笔记

55 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第五天。 今天学习的内容是如何写好JavaScript(下),因为经过昨天的学习,所以今天的课程的内容了解的比较透彻,本节课的主要内容就是对昨天内容的一个复习加上一些经典的案例实战。

本堂课重点内容

  • 一段代码是否好坏的概述
  • 交通灯案例的三种优化
  • 一些算法的举例

详细知识点介绍

详细知识点依旧是分享在文章末尾。

课后个人总结

今天通过交通灯案例的几种优化,对昨天轮播图案例以及封装优化有了更加深入的理解,并且我还认识到了算法的重要性,想要进入好的公司,即使是前端工程师,也是要学习好算法和数据结构的,同时对一些前沿技术的了解对自己以后也是有很大的帮助的。

笔记总结

如何写好JavaScript(下)

先来看一段代码:

// 判断一个mat2d矩阵是不是单位矩阵
function isUnit(m) {
    return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0;
}

这其实是一段真实的代码:

  get layerTransformInvert() {
    if(this[_layerTransformInvert]) return this[_layerTransformInvert];
    const m = this.transformMatrix;
    if(m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0) {
      return null;
    }
    this[_layerTransformInvert] = mat2d.invert(m);
    return this[_layerTransformInvert];
  }

我们在评判代码的过程中不能只是简单的单独评价一段代码写的好还是不好,只有将代码放在最合适的应用场景中,才能真正评判代码的效率高低。

1、交通灯状态切换

(1)版本一

  • html
<ul id="traffic" class="wait">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
  • css
#traffic {
  display: flex;
  flex-direction: column;
}
​
#traffic li{
  list-style: none;
  width: 50px;
  height: 50px;
  background-color: gray;
  margin: 5px;
  border-radius: 50%;
}
​
#traffic.s1 li:nth-child(1) {
  background-color: #a00;
}
​
#traffic.s2 li:nth-child(2) {
  background-color: #aa0;
}
​
#traffic.s3 li:nth-child(3) {
  background-color: #0a0;
}
​
#traffic.s4 li:nth-child(4) {
  background-color: #a0a;
}
​
#traffic.s5 li:nth-child(5) {
  background-color: #0aa;
}
  • js
/*  普通实现  */
const traffic = document.getElementById('traffic');
​
(function reset(){
  traffic.className = 's1';
  
  setTimeout(function(){
      traffic.className = 's2';
      setTimeout(function(){
        traffic.className = 's3';
        setTimeout(function(){
          traffic.className = 's4';
          setTimeout(function(){
            traffic.className = 's5';
            setTimeout(reset, 1000)
          }, 1000)
        }, 1000)
      }, 1000)
  }, 1000);
})();

(2)版本二(数据抽象)

/* 数据抽象 */
const traffic = document.getElementById('traffic');
​
const stateList = [    { state: 'wait', last: 1000 },    { state: 'stop', last: 3000 },    { state: 'pass', last: 3000 },];
​
function start(traffic, stateList) {
    function applyState(stateIdx) {
        const { state, last } = stateList[stateIdx];
        traffic.className = state;
        setTimeout(() => {
            applyState((stateIdx + 1) % stateList.length);
        }, last)
    }
    applyState(0);
}
​
start(traffic, stateList);

(3)版本三(过程抽象)

/* 过程抽象 */
const traffic = document.getElementById('traffic');
​
function wait(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
​
function poll(...fnList) {
    let stateIndex = 0;
​
    return async function (...args) {
        let fn = fnList[stateIndex++ % fnList.length];
        return await fn.apply(this, args);
    }
}
​
async function setState(state, ms) {
    traffic.className = state;
    await wait(ms);
}
​
let trafficStatePoll = poll(setState.bind(null, 'wait', 1000),
    setState.bind(null, 'stop', 3000),
    setState.bind(null, 'pass', 3000));
​
(async function () {
    // noprotect
    while (1) {
        await trafficStatePoll();
    }
}());
​

(4)版本四(异步 + 函数式)

/* 异步 + 函数式 */
const traffic = document.getElementById('traffic');
​
function wait(time) {
    return new Promise(resolve => setTimeout(resolve, time));
}
​
function setState(state) {
    traffic.className = state;
}
​
async function start() {
    //noprotect
    while (1) {
        setState('wait');
        await wait(1000);
        setState('stop');
        await wait(3000);
        setState('pass');
        await wait(3000);
    }
}
​
start();

2、算法举例

算法举例的话,讲师就是讲解了几个经典的算法,比如4的幂、分红包等算法,这里不再总结算法知识。