这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天。
一、JavaScript编码原则
1、各司其职:让HTML、CSS、JavaScript职能分离
月影在这里举了个例子:对页面进行黑底与白底的切换。
版本一:
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(e.target.innerHTML === '🌞') {
body.style.backgroundColor = 'black';
body.style.color = 'white';
e.target.innerHTML = '🌜';
} else {
body.style.backgroundColor = 'white';
body.style.color = 'black';
e.target.innerHTML = '🌞';
}
});
版本二:
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
const body = document.body;
if(body.className !== 'night') {
body.className = 'night';
} else {
body.className = '';
}
});
这两个版本中第二种很明显是更符合规范的,因为这第二版并没有直接的去修改样式,而是切换样式,这一个版本很好的将css与Javascript分离了。
版本三:
<input id="modeCheckBox" type="checkbox">
<div class="content">
<header>
<label id="modeBtn" for="modeCheckBox"></label>
<h1>深夜食堂</h1>
</header>
<main>
<div class="pic">
<img src="<https://p2.ssl.qhimg.com/t0120cc20854dc91c1e.jpg>">
</div>
<div class="description">
<p>xxx
</div>
</main>
</div>
#modeCheckBox {
display: none;
}
#modeCheckBox:checked + .content {
background-color: black;
color: white;
transition: all 1s;
}
在这一版本里面直接不使用js来进行操作。这一个版本是在html前面增加了一个checkbox,使用了伪类选择器在checkbox状态改变的时候也选定了要修改的样式。而选择checkbox的功能则是在点击按钮上用for循环将checkbox放入了标签之中进行连接完成操作。
结论:
1、HTML、CSS、JS应该各司其责,分别控制内容、样式和交互操作。
2、应当避免不必要的用js去直接操作修改样式
3、可以用class来表示状态
4、纯展示类的交互可以去寻求零js方案
2、组件封装
组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性。
这里的例子是用原生JS写一个轮播图的组件。
首先在写组件时,先确定组件的结构(HTML)。在这里轮播图是一个典型的列表结构,可以用无序列表ul元素来实现。
然后确定组件的表现(CSS)。这里可以用绝对定位将图片重叠在一起,切换的状态使用修饰符(modifier),切换动画使用CSS中的transition。
然后要设定它的行为,首先是设置API,比如这里使用slider类里面写了几个slideTo()、slideNext()等API。
然后除了API之外,还要设置控制流(Event)。
设定完组件之后,可以对它进行插件化(重构)。解耦指的是将控制元素抽取成插件,然后插件与组件之间通过依赖注入的方式来建立联系,根据需求来选择要注册的插件(功能)。
然后也可以将它模板化,即将HTML进行模板化,可以更加易于扩展。
对组件框架的抽象则可以将组件的通用模型抽象出来,更加方便复用。
3、编程范式
过程抽象:让某个需求覆盖不同的事件处理。比如只让某个事件执行一次的函数可以抽象出来。
高阶函数HOF:以函数作为参数和返回值,常常用作于函数装饰器。 有:Once、Throotle(节流函数)、debounce、consumer、interative
编程范式:
1、命令式(强调怎么做)
2、声明式(强调做什么,简洁)
有时候命令式看着更方便,但是如果要修改时要对命令式的代码进行修改,而在声明式中则假如一个状态就行,不用大部分修改,即声明式有着更大的可拓展性。
二、JavaScript代码质量优化
月影举了个例子:交通灯切换,五层嵌套setTimeout的代码不美观,可以把状态数据抽象出来,每次选择一个数据并展示;也可以使用过程抽象,不过较为复杂,但是可以拓展性较强,其他相关函数也可使用,但是要注意是否过度抽象;还可以使用异步函数进行,这样子做可读性与简洁性都不错。
还介绍了4的幂和洗牌问题。
以及分红包问题:
切西瓜法:每次随机拆为两部分,然后不断选择最大的去进行拆分。
抽牌法:把金额当作数列,在数列中随机插入多个分隔符,分割符之间便是要分的金额,空间复杂度比较高
结论: 在进行JS代码编写时,应该根据场景考虑代码的可读性、拓展性,应当适度抽象,不能过度抽象。并且应该考虑多种执行方案,让代码更加简洁高效。