preface

Preliminary review

How to write good JavaScript is certainly a problem that every front-end engineer has been thinking about. The teacher told us some principles of writing good JavaScript, and also taught us some skills of how to write good JavaScript. Today, let’s continue to learn JavaScript with the teacher!

  • How to Write JS well

  • How to Write JS Well

This is real code

Github.com/spritejs/sp…

In fact, this is a piece of real code for the spriteJs framework, you can go to line 131 to see!SpriteJs is a cross-terminal Canvas drawing framework open source by 360 Qiqi Dance Company. It can quickly draw structured UI, animation and interactive effects based on Canvas. Is a cross-platform 2D drawing object model library, it can support web, Node, desktop application and wechat small program graphics drawing and achieve a variety of animation effects.

What do you care most about when writing code?

Left-pad incident of the year

function leftpad(str, len, ch){ str = String(str); var i = -1; if(! ch && ch ! == 0) ch = ""; len = len - str.length; while(++i < len){ str = ch + str; } return str; }Copy the code

There are many slots in the event itself

  • NPM module granularity

  • Code style.

  • Code quality/efficiency

  • Cleaner code

  • efficiency

Repeat polyfill/MDN

  • Better performance

  • To optimize the

Traffic light: State switch

To achieve a switch over the state of multiple traffic lights switch function

Version of a

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

Version 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);
Copy the code

Version 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(); }} ());Copy the code

Version 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();
Copy the code

Check if it’s a power of four

Version of a

function isPowerOfFour(num) { num = parseInt(num); While (num > 1) {// If (num % 4) return false; num /= 4; } return true; }Copy the code

Version 2

function isPowerOfFour(num) { num = parseInt(num); While (num > 1) {// If (num & 0b11) return false; Num >>>= 2; } return true; }Copy the code

Version 3

function isPowerOfFour(num) { num = parseInt(num); Return num > 0 && //num and num-1 = 0 && // Num & (num -1) === 0 && // Num & (num -1) === 0 && // Num & (num -1) === 0 && // Num & (num -1) === 0 && // Num & (num -1) === 0; }Copy the code

Version 4

Function isPowerOfFour(num) {// Convert to a binary string num = parseInt(num).toString(2); Return /^1(? :00)*$/.test(num); }Copy the code

Shuffle the deck

const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; Function shuffle(cards) {return [...cards].sort(() => math.random () > 0.5? 1:1); } console.log(shuffle(cards));Copy the code

correctness

const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; Function shuffle(cards) {return [...cards].sort(() => math.random () > 0.5? 1:1); } const result = Array(10).fill(0); for(let i = 0; i < 1000000; i++) { const c = shuffle(cards); for(let j = 0; j < 10; j++) { result[j] += c[j]; } } console.log(result);Copy the code

Version of a

Each time, draw a card at random and move it to the last position.

const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

function shuffle(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]];
  }
  return c;
}

const result = Array(10).fill(0);

for(let i = 0; i < 10000; i++) {
  const c = shuffle(cards);
  for(let j = 0; j < 10; j++) {
    result[j] += c[j];
  }
}

console.log(shuffle(cards));
console.log(result);
Copy the code

Version 2

const cards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

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];
  }
}

const result = draw(cards);
console.log([...result]);
Copy the code

Share out bonus package

Version of a

Every time we divide the amount into two parts, there will always be a large part and a small part. We pick the largest part and divide it, and then pick the largest part from the current part. This method distributes red packets relatively evenly.

function generate(amount, count){ let ret = [amount]; While (count > 1){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; }Copy the code

Version 2

If you cut 100 yuan by 9 cuts and there are 9999 positions to cut, then this problem can be converted to a shuffle problem, cut the positions from 1 to 9999, then shuffle the 9999 numbers randomly, and divide them into 10 positions, then cut. The back position – the front position gets the size of the split.

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;
}
Copy the code

conclusion

  • If there is any mistake above, please point out in the comment section, thank you!

After reading it, give it a thumbs-up and then walk away