3.如何写好 JS
1.原则
-
各司其职
- HTML/CSS/JS 各司其职
- 应当避免不必要的由JS直接操作样式
- 可以用class来表示状态
- 纯展示类交互寻求 零JS方案
-
组件封装
组件:是指Web页面上抽出来一个个包含模板(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、拓展性、复用性。
-
结构设计
-
展现效果
-
行为设计
- API(功能)
- Event (控制流)
- 重构:插件化
-
将控制元素抽取成插件
-
插件与组件之间通过依赖注入方式建立联系
行为设计:
- 过程抽象
- 用来处理局部细节控制的一些方法
- 函数式编程思想的基础应用
2.高阶函数
- 以函数作为参数
- 以函数作为返回值
- 常用于作为函数装饰器
Once函数
function once(fn){
return function(...args){
if(fn){
const ret = fn.apply(this,args)
fn = null
return ret
}
}
}
节流函数 throttle
function throttle(fn,time=500) {
let timer;
return function(...args){
if(timer==null){
fn.apply(this,args);
timer=setTimeout(()=>{
timer=null
},time)
}
}
}
防抖debounce
function debounce(fn,dur){
dur = dur||100
var timer;
return function () {
clearTimeout(timer)
timer=setTimeout(()=>{
fn.apply(this,arguments);
},dur)
}
}
consumer
时间间隔操作
function consumer(fn,time){
let tasks = [],
timer;
return function(...args){
tasks.push(fn.bind(this,...args));
if(timer ==null){
timer = setInterval(()=>{
tasks.shift().call(this)
if(tasks.length<=0){
clearInterval(timer);
timer=null
}
},time)
}
}
}
迭代 iterative
const isIterable=obj=>obj!=null&&typeof obj[Symbol.iterator] === 'function'
function iterative(fn){
return function(subject,...rest){
if (isIterable(subject)){
const ret = []
for(let obj of subject){
ret.push(fn.apply(this,[obj,...rest]))
}
return ret
}
return fn.apply(this,[subject,...rest])
}
}
\