初学JavaScript
这是我参与【第四届青训营】笔记创作活动的第3天,今天对JavaScript的一些学习做总结与笔记一、写好JS的一些原则
- 各司其职
- 让HTML,CSS和JavaScript职能分离
- 组件封装
- 好的UI组件具备正确性、扩展性和复用性
- 过程抽象
- 应用函数式编程思维
1。各司其责
例子:深夜食堂
写一段JS,控制一个网页,让它支持浅色和深色两种模式。如何实现?
版本一:
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里定义了className,night表示夜间模式,没有night的话就默认白天模式;否则夜间模式。
此优化让程序员能更加直观看出所表示的意图,也更加简洁。
版本三:
html:
<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>
这是一间营业时间从午夜十二点到早上七点的特殊食堂。这里的老板,不太爱说话,却总叫人吃得热泪盈
眶。在这里,自卑的舞蹈演员偶遇隐退多年舞界前辈,前辈不惜讲述自己不堪回首的经历不断鼓舞年轻人,最终令其重拾自信;轻言绝交的闺蜜因为吃到共同喜爱的美食,回忆起从前的友谊,重归于好;乐观的绝症患者遇到同命相连的女孩,两人相爱并相互给予力量,陪伴彼此完美地走过了最后一程;一味追求事业成功的白领,在这里结交了真正暖心的朋友,发现真情比成功更有意义。食物、故事、真情,汇聚了整部剧的主题,教会人们坦然面对得失,对生活充满期许和热情。每一个故事背后都饱含深情,情节跌宕起伏,令人流连忘返 [6] 。
</p>
</div>
</main>
</div>
css:
#modeCheckBox {
display: none;
}
#modeCheckBox:checked + .content {
background-color: black;
color: white;
transition: all 1s;
}
用纯HTML和CSS实现此功能,给checkbox设置一个check的状态,用check的状态去设置content的样式,去把background-color和color切换状态。
深夜食堂——结论:
- HTML/CSS/JavaScript各司其责
- 应当避免不必要的由JS直接操作样式
- 可以用class来表示状态
- 纯展示类交互寻求零JS方案
2。组件封装
组件是指Web页面上抽出来一个个包含模板(HTML)、功能(JSS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性和复用性。例子:用原生JS写一个电商网站的轮播图,该怎么实现?
2.1定义一个html结构
结构(html):轮播图是一个典型的列表结构,我们可以使用无序列表ul元素来实现。
<div id="my-slider" class="slider-list">
<ul>
<li class="slider-list__item--selected">
<img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png">
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg">
</li>
<li class="slider-list__item">
<img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg">
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg">
</li>
</ul>
</div>
呈现出来是这个效果
2.2表现:CSS
- 使用 CSS 绝对定位将图片重叠在同一个位置
- 轮播图切换的状态使用修饰符(modifier)
- 轮播图的切换动画使用 CSS transition
#my-slider{
position: relative;
width: 790px;
}
.slider-list ul{
list-style-type:none;
position: relative;
padding: 0;
margin: 0;
}
.slider-list__item,
.slider-list__item--selected{
position: absolute;
transition: opacity 1s;
opacity: 0;
text-align: center;
}
.slider-list__item--selected{
transition: opacity 1s;
opacity: 1;
}
2.3行为:JS
①API
- Slider
- +getSelectedItem()
- +getSelectedltemIndex()
- +slide To()
- +slideNext()
- +slidePrevious()
②控制流
- 使用自定义事件来解耦
用控制流来添加控制的点
总结:基本方法
- 结构设计
- 展现效果
- 行为设计
- API(功能)
- Event(控制流)
重构:插件化
解耦
- 将控制元素抽取成插件
- 插件与组件之间通过依赖注入方式建立联系
模板化
- 将HTML模板化,更易于扩展
组件框架
抽象化
- 将组建通用模型抽象出来
总结:
- 组件设计的原则:封装性、正确性、扩展性、复用性
- 实现组件的步骤:结构设计、展现效果、行为设计
- 三次重构
- 插件化
- 模板化
- 抽象化(组件框架)
3.过程抽象
- 用来处理局部细节控制的一些方法
- 函数式编程思想的基础应用
例子:操作次数限制
- 一些异步交互
- 一次性的HTTP请求
3.1高阶函数
①Once:
为了能够让“只执行一次“的需求覆盖不同的事件处理,我们可以将这个需求剥离出来。这个过程我们称为过程抽象。
function once(fn) {
return function(...args) {
if(fn) {
const ret = fn.apply(this, args);
fn = null;
return ret;
}
}
}
②高阶函数(HOF):
- 以函数作为函数
- 以函数作为返回值
- 常用于作为函数装饰器
function HOF0(fn) {
return function(...args) {
return fn.apply(this, args);
}
}
③常用高阶函数:
- Once:确保给定函数只能被调用一次,从而防止重复初始化。
- Throttle:限制一个函数在一定时间内只能执行一次。
- Debounce:强制一个函数在某个连续时间段内只执行一次,哪怕它本来会被调用多次。
- Consumer/2:是一个函数式接口,它可以接受一个泛型 类型参数,进行处理后无任何返回值。
- Iterative:可迭代,它会返回新的函数,在新函数中进行判断。如果可迭代,迭代的调用新函数里,如果不可迭代,则只执行一次。
4.编程范式
编程范式有三种:命令式、声明式和函数式。
4.1命令式
强调怎么做,是关注计算机执行的步骤,一步步告诉计算机先做什么再做什么。
-
面向过程 -
面向对象
4.2声明式
强调做什么,是以数据结构的形式来表达程序执行的逻辑。即告诉计算机应该做什么,但不指定具体要怎么做,简化了代码。
总结:
- 过程抽象/HOF/装饰器
- 命令式/声明式