这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
写代码最应该关注什么
- 使用场景
- 风格
- 效率
- 设计
- 约定
Leftpad事件
- 事件本身槽点
- NPM模块粒度
- 代码风格
- 代码质量/效率
- 更改后
- 代码更简洁
- 效率提升
案例
交通灯:状态切换
- 版本一
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);
- 版本二:过程抽象,灵活性比较强
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();
}
}());
- 版本三:异步函数(比较简单)
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();
判断是否是4的幂
- 版本一(最简单但性能较差)
function isPowerOfFour(num){
num = parseInt(num);
while(num > 1){
if(num % 4) return false;
num /= 4;
}
return true;
}
- 版本二(性能还是不够好)
function isPowerOfFour(num){
num = parseInt(num);
while(num > 1){
if(num & 0b11) return false;
num >>>= 2;
}
return true;
}
- 版本三(性能最好)
时间复杂度为O(1)
function isPowerOfFour(num){
num = parseInt(num);
return num > 0 &&
(num & (num - 1)) === 0 &&
(num & 0xAAAAAAAA) === 0;
}
num.addEventListener('input', function(){
num.className = '';
});
checkBtn.addEventListener('click', function(){
let value = num.value;
num.className = isPowerOfFour(value) ? 'yes' : 'no';
});
- 另一种方法(比较有趣,性能也还可以)
正则表达式
function isPowerOfFour(num){
num = parseInt(num).toString(2);
return /^1(?:00)*$/.test(num)
}
洗牌
- 版本一(不正确的)
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));
- 版本二(正确)
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);
分红包
- 切西瓜法(代码略)
Day2总结与思考
其实对于JS,我们应该先明白我们该如何写好JS,最重要是有三个原则:
-
各司其职
- HTML
- CSS
- JS
-
组件封装
- 复用性
- 可拓展性
- 正确性
-
过程抽象
- 插件化
- 模板化
- 实现组件框架
- 局部细节/行为的时候 函数式编程的基本应用 JS也具有声明式和命令式,但声明式有更强的可拓展性,所以在写JS时应该要考虑清楚是使用声明式还是命令式
其实在写代码时,主要是考虑使用场景,而不是一味的追求性能,还是得多思考,而不是一股脑地写复杂的代码。
虽然前端用的算法较少,但对于算法还是基本功,不能忽略,所以还是要学好数学,学好算法为以后着想,希望自己能开始学习算法,锻炼自己的思维能力,在之后能写出一些好的有质量的代码。