跟着月影学JavaScript|青训营笔记

87 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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代码编写时,应该根据场景考虑代码的可读性、拓展性,应当适度抽象,不能过度抽象。并且应该考虑多种执行方案,让代码更加简洁高效。