写好JavaScript | 青训营笔记

41 阅读2分钟
  • 这是我参与第五届青训营伴学笔记创作活动的第4天

LeftPad事件

  • 事件本身并不是一个很大的问题,但是当代码被摆在各位大神面前的时候,总是各种方案来优化你的代码。这可能就是code review的魅力所在吧。
  • 下面就是一个简单的 快速幂 的方法,引发的讨论。
while(n) {
    if(n%2 == 1){
        result += string;
    }
    if(n > 1){
        string += string;
    }
    n>>=1;
}
return result;

JavaScript代码质量

  • 可读性
  • 可扩展性

交通灯状态切换案例

暴力做法

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);
})();

数据抽象 优雅递归

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(stateId) {
    const {state, last} = stateList[stateIdx];
    traffic.className = state;
    setTimeout(()=>{
      (stateIdx+1) % stateList.length;
    }, last);
    applyState(0);
  }
}

start(traffic, stateList);

过程抽象

function wait(time) {
  return new Promise(resolve => setTimeout(resolve, time));
}

function setState(state) {
  traffic.className = state;
}

async function start() {
  while(1) {
    setState('wait');
    await wait(1000);
    setState('stop');
    await wait(3000);
    setState('pass');
    await wait(3000);
  }
}
start();

判断是否为4的幂

普通操作

function isPowerOfFour(num) {
  num = parseInt(num);

  while(num > 1){
    if(num%4 !== 0) return false;
    num /= 4;
  }
  return num === 1;
}
### 位操作
```js
function isPowerOfFour(num) {
  num = parseInt(num);

  while(num > 1){
    if(num & 0b11) return false;
    num >>>= 2;
  }
  return num === 1;
}

奇怪操作 复杂度 O(1)

function isPowerOfFour(num) {
  num = parseInt(num);

  return num > 0 &&
        (num & (num-1)) === 0 &&
        (num & 0xAAAAAAAAAAAAA) === 0;
}

正则表达式

// 正则表达式
function isPowerOfFour(num) {
  num = parseInt(num).toString(2);

  return /^1(?:00)*$/.test(num)
}

红包生成器

每次都去切分最大的红包

  • 结果会比较均分
function generate(amount, count) {
  let ret = [amount];

  while(count > 1) {
    console.log(...ret);
    let cake = Math.max(...ret),
        idx = ret.indexOf(cake),
        part = 1 + Math.floor((cake/2) + Math.random()),
        rest = cake - part;
    ret.splice(idx, 1, part, rest);
    count--;
  }
  return ret;
}

console.log(generate(100.00, 10));

抽牌法

  • O(n)复杂度 空间复杂度较高
  • 比较随机,通过随机抽取的方式
function * draw(cards) {
  const c = [...cards];

  for(let i=c.length; i>0; i--){
    const pIdx = Math.floor(Math.random() * i);
    [c[pIdx], c[i-1]] = [c[i-1], c[pIdx]];
    yield c[i-1];
  }
}

function generate(amount, count) {
  if(count <= 1) return [amount];
  const cards = Array(amount-1).fill(0).map((_, i) => i+1);
  const pick = draw(cards);
  const result = [];
  for(let i=0; i<count; i++){
    result.push(pick.next().value);
  }
  result.sort((a, b) => a-b);
  for(let i=count-1; i>0; i--){
    result[i] = result[i]-result[i-1];
  }
  return result;
}

console.log(generate(1000, 10));