JS规范 | 青训营笔记

97 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

JS规范 | 青训营笔记

编码原则

⭐原则一:各司其职

各司其职,就是让html、css与js分别管好分内的事情,html做结构,css改样式,js做交互,耦合度太高则会导致维护困难。

例如要做用户点击后改变样式的功能,如果直接通过js进行样式修改:

元素.style.样式 = "..."

就会使样式固定在了js中

所以我们更推荐将要应用的样式写在css中,再在js中修改类来达到修改样式的目的:

元素.className = "..."

继续优化👇

我们上节课就讲过伪类选择器,可以为不同状态的元素设置样式,例如

#modeCheckBox:checked {
    ...
}

通过checked来选择被勾中的checkbox元素,这样我们就可以在里面设置激活后需要应用的内容

而我们可以用一个label与这个checkbox进行关联:

<label id="modeBtn" for="modeCheckBox">点我点我</label>

这样点击多选框对应的label文字,就可以实现checkbox更换状态效果

最后我们再将checkbox的display属性设为none,隐藏显示,大功告成!

结论

  • HTML/CSS/JS应当各司其职
  • 我们要尽量避免由JS直接操作样式
  • 可以用class来表示状态
  • 纯展示类的交互要寻求零JS方案

⭐原则二:组件封装

组件时指Web页面上抽出来的一个个包含模板(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性。

组件,例如轮播图、商品清单、工具栏等等,这些组件比较常见,复用性较强,我们可以写出其一个个单独封装好的组件,这样在之后需要应用时,只需要将之前写好的组件插入进去便可以。

在封装过程中,我们要注意组件内部的功能或样式组件之间仍需解耦:比如我们需要更换组件内的一些按键样式、图标、添加新的功能等,如果耦合太高,我们更改一个就要改动html、css、js全局,这样反而更加繁琐,所以我们需要单独再将内部的方法作为插件的形式在总组件中实现依赖注入,以便之后修改,最终,html部分也可由js来生成,实现html的模板化。

到这里封装过程大致已经完成,最后一步便可将所有组件的通用方法抽出来,作成父类,减少代码冗余。

总结

我们在实现组件时,有三大步骤:结构设计、展现效果、行为设计

实现后进行优化,进行了三次重构:

  • 插件化
  • 模板化
  • 抽象化(最终实现了组件框架)

要注意组件化并没有破坏第一点各司其职的原则,写在哪里并不影响它做什么事情,由JS进行html封装,html仍然用来表示结构,发挥的仍是其本身的作用!

⭐原则三:过程抽象

  • 用来处理局部细节控制的一些方法
  • 函数式编程思想的基础应用

老师上课的举例:

如何让一个事件只触发一次?

答:当事件触发,对应方法执行后,我们就将该方法指向设为null,这样下次再次触发该事件调用的只是null,也就不会再次执行对应方法。

在一个项目中,可能不止有一个事件只需执行一次,我们就可以将设置方法只执行一次的功能部分抽离出来,设为单独的函数:

function once(fn){
    return function(...args){
        if(fn){
            const ret = fn.apply(this, args);
            fn = null;
            return ret;
        }
    }
}

这样将功能抽离,就叫做过程抽象

而这样传入值为函数,返回值也为函数的函数,就称作高阶函数。

我们为什么需要高阶函数呢?

先来看两个概念:

  • 纯函数:返回值只由传入值确定,与外界交换数据只有这一个通道
  • 非纯函数:返回值不止或不由由传入值确定,而是通过隐式的方式与外界进行数据交换

纯函数由于其特性,更加方便移植、维护且可读性强,而非纯函数的不确定性增加了维护困难,所以我们更加推荐在开发时尽可能使用纯函数,我们使用高阶函数的其中一个目的也是将非纯函数封装拓展成纯函数

命令式与声明式

命令式:告诉程序怎么做

let list = [1,2,3,4];
let mapl = [];
for(let i = 0;i < list.length; i++){
    mapl.push(list[i] * 2);
}

声明式:告诉程序做什么

let list = [1,2,3,4];
const double = x => x * 2;
list.map(double);

当要判断或执行的内容很多时,光用循环或if-else会使代码很长,且扩展性很弱,而声明式中调用已封装好的函数,传入需要处理的内容,当内容发生变动时,只需要改动传入值即可,易读且扩展性强,这也是过程抽象的一个高效应用。

总结

今天详细学习了js的编写规范,代码不仅仅是写出来就可以,还需要考虑其性能、易读、耦合度等,好的代码总能让人拍手称赞耳目一新,在过程抽象里面仍有部分内容还未完全理解与掌握,仍需巩固!