这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
写好JS的一些原则
- 各司其责:让HTML、CSS和JavaScript职能分离。
- 应当避免不必要的由JS直接操作样式
- 可以用class来表示状态
- 纯展示类交互寻求零JS方案
- eg:夜间白天切换,尽量分开CSS和Javascript的部分,样式的变化在CSS中,Javascript只改变class的状态,或者直接用CSS的伪类选择器改变样式
- 组件封装:好的UI组件具备正确性、扩展性、复用性。
- 结构设计html
- 展现效果css
- 行为设计JavaScript : API (功能)、Event (控制流)
- 将控制元素抽取成插件
- 插件与组件之间通过依赖注入方式建立联系
- 将HTML模板化,易于扩展(在Javascript中根据数据生成对应的html文本)
- 将通用组件模型抽象出来
- 过程抽象:应用函数式编程思想。
- 高阶函数实现(以函数为参数,以函数为返回值,常用作函数装饰器),eg:让函数只执行一次抽象得到的once()函数
⭐重构:插件化
//高阶函数基本架构
function HOFO(fn) {
return function(..args) {
return fn,apply(this, args);
}
}
//once高阶函数实现
function once(fn) {//输入的是一个函数
return function (...args) {
if(fn) {//只有第一次执行的时候fn!=null,之后都是null
const ret = fn.apply(this, args);
fn=null;//用这个
return ret ;
}
};
}
function throttle(fn, time = 500){
let timer;//只执行一次
return function(...args){
if(timer == null){
fn.apply(this, args);
timer = setTimeout(() => {
timer = null;//执行完这句才能再次执行这个函数
}, time)
}
}
}
高阶函数的使用可以减少非纯函数(输出不确定)的出现。
//将列表中的奇数位置元素设置为红色
const isIterable = obj => obj != null
&& typeof obj[Symbol.iterator] === 'function';
function iterative(fn) {
return function(subject, ...rest) {
if(isIterable(subject)) {//这里会判断subject是否是一个列表,如果是,那么列表中的每一个元素+...rest执行该函数
const ret = [];
for(let obj of subject) {
ret.push(fn.apply(this, [obj, ...rest]));
}
return ret;
}
return fn.apply(this, [subject, ...rest]);
}
}
const setColor = iterative((el, color) => {
el.style.color = color;
});
const els = document.querySelectorAll('li:nth-child(2n+1)');
setColor(els, 'red');
//状态转换(声明式)
function toggle(...actions){
return function(...args){
let action = actions.shift();
actions.push(action);
return action.apply(this, args);
}
}
switcher.onclick = toggle(
evt => evt.target.className = 'off',
evt => evt.target.className = 'on'
);
如果增加状态是很容易的,只要在第二个函数添加状态即可。如果采用if-else增加状态就比较麻烦了。这就是命令式(怎么做)与声明式(做什么)的区别。
如何更好地优化代码
- 交通灯:嵌套🙁、抽象😊(不要过度抽象)
- 4的幂:
function isPowerOfFour(num){
num = par seInt(num) ;
return num > 0 &&
(num&(num-1))===0&&//判断是否为2的幂(eg:8&7=0,7&6!=0)
(num & 0xAAAAAAAA) === 0;//判断是否为4的幂(4=100,4的幂1必然在奇数位,0xAAAAAAAA=1010...1010)
}
function isPowerOfFour(num){
num = parseInt(num).toString(2);
return /^1(?:00)*$/.test(num);//4的幂1必然在奇数位
}
- 分红包:切西瓜法、抽牌法