这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
关于JavaScript
写好js的原则
- 各司其职,让html、css和JavaScript职能分离
//用一个不显示的选择框控制样式
<input id="modeCheckBox" type="checkbox">
<div class="content">
<header>
<!--for属性可以使label和同id标签的状态一样-->
<label id="modeBtn" for="modeCheckBox"></label>
<h1>深夜食堂</h1>
</header>
<main>
</main>
</div>
#modeCheckBox{
display:none;
}
#modeCheckBox:checked + .content {
background-color:black;
color:white;
transition:all 1s;
}
- 组件封装:
- 原则:好的UI组件具备正确性、扩展性、复用性
- 步骤:结构设计,展现效果,行为设计(API功能,Event控制流)
- 插件化:将控制元素抽取成插件,插件与组件之间通过依赖注入建立联系
- 模板化:将html模板化更易于扩展
- 抽象化:把通用的组件模型抽象出来再继承
- 过程抽象:启用函数式编程思想,处理局部细节控制的一些方法
- 高阶函数HOF:以函数作参数,以函数作返回值,常用于作函数装饰器
- 常用高阶函数:once、throttle、debounce、consumer/2、iterative
- 命令式:更注重过程怎么做
- 声明式:更注重结果做什么
//只执行一次
function once(fn){
return function(...args){
if(fn){//执行一次后把参数置为null了为false
const ret = fn.apply(this,args);
fn=null;
return ret;
}
}
}
//命令式
switcher.onclick=function(evt){
if(evt.target.className==='on'){
evt.target.className='off';
}else{
evt.target.className='on';
}
}
//声明式
function toggle(...actions){
return function(...args){
let action = actions.shift();
actions.push(action);
return action.apply(this,args);
}
}
switvher.onclick = toggle{
evt=>evt.target.className='off';
evt=>evt.target.className='on';
}
- 写代码注重:风格、效率、约定、使用场景、设计
- 举了三个例子,信号灯、抽牌、分红包(切西瓜、抽牌法)
//信号灯
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 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]);