[ JavaScript 编码原则 | 青训营笔记]

104 阅读7分钟

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

一、本堂课重点内容:

  • JavaScript 好代码的标准
  • HTML/CSS/JS 各司其责
  • 组件的定义解析及特征
  • 组件封装基本方法
  • 过程抽象概念
  • 高阶函数使用模式
  • JavaScript编程范式

二、详细知识点介绍:

1. JavaScript 好代码的标准

写好JS的原则:各司其职、组件封装、过程抽象。

2. HTML/CSS/JS 各司其责

html负责结构、css负责表现、js负责行为,结构、表现、行为分离是基本原则。

代码优化案例:网页的日间与夜间模式切换。

image.png

各司其职优化版本:

image.png

css版本:由于切换功能只需要css就可以实现,因此可以不需要js。

label中的for属性值为被隐藏起来的checkbox的id,因此点击label等同于点击checkbox。当checkbox处于checked状态,会使用checked中的样式,由此实现切换。同样,凡仅涉及样式切换的操作,都可以用class表示状态,用纯css实现。

image.png

3. 组件的定义解析及特征

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

例:轮播图组件

结构(HTML):典型的列表结构,可以用无序列表实现。

image.png

表现(CSS):使用绝对定位将图片重叠在同一位置,使用修饰符进行状态切换,使用CSS transition实现切换动画。

image.png

行为(JS):使用API实现图片切换。在Slider类中,首先使用构造函数获得列表以及列表项,再使用getSelectedItem()和getSelectedItemInde()被选中的项及其index,然后通过slideNext()和slidePrevious()计算index切换不同的列表项,通过slideTo()修改原选中列表项和新选中列表项的className进行状态切换。使用时只需在外部new一个Slider,然后使用setInterval实现每两秒使用slideNext()切换到下一张图片即可。

image.png

image.png

以上的方式只能实现一个自动切换的轮播图,而一般的轮播图具有下方的选择某张图片的功能,以及左右箭头切换上/下一张图的功能。

image.png

因此还需要在HTML页面中加入以下内容:

两个a标签表示左右切换按钮,四个span标签表示下方小圆点。

image.png

在JS上添加了controller表示下方小圆点,监听mouseover和mouseout事件,实现鼠标在某圆点上时,切换到对应图片并停止轮播,移开后又重新自动轮播的操作。

image.png

同时还要通过监听,实现将红点切换到鼠标所在位置的操作。

image.png

在slideTo中增加了部分代码,创建slide事件,用于小圆点监听。

image.png

previous和next对应两个左右切换按钮,点击后停止轮播,切换到对应图片后重新开启轮播。

image.png

最后还新增了start和stop代码用于开启和停止轮播,由于slider的构造函数中包含默认值为3000的参数cycle,用于控制图片切换间隔,所以使用时只需要创建slider并调用slider.start(),不需要setInterval来实现轮播了。

image.png

4. 组件封装基本方法

  • 插件化:

为了提高组件的复用性和灵活性,可以将控制元素抽取成插件,插件与组件之间通过依赖注入方式建立联系。

首先在Slider类中加入可以注入插件的接口,

image.png

将四个小圆点以及左右箭头插件抽象出来,注入后可用于控制slider。

image.png

使用时进行插件注册即可添加该插件的功能。若某一插件未被注册,该插件不会消失,而是无法使用,实现插件删除应删除对应HTML元素。

image.png

  • 模板化:

将HTML模板化,使其更易于扩展。

轮播图组件在HTML中被简化为一个div容器,通过render方法将传入的图片变成列表项后生成列表,使用innerHTML插入。

image.png image.png

创建插件的方法也分为了render方法和action方法,render方法渲染内容,action方法完成初始化。当不需要某个插件时,不进行注册,会将功能和显示一同删除。

image.png

创建slider时将需要展示的图片传入即可。

image.png

  • 抽象化

构建一个组件模板,Slider类继承Component类,其余一致。

image.png

5. 过程抽象概念

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

例如点击某个列表项时,会在播放两秒的fadeout动画后删除,但如果在动画播放期间多次点击则会报错。该问题可以通过加上once:true解决。

image.png

上述这种多次调用只允许执行一次的方式,也可以将过程封装成一个叫做once的高阶函数实现。

image.png

once简单示例:当使用once函数时,即使调用三次,也只会实现一次。

image.png

once方法原理:运行一次函数后,设fn为null,第二次就无法运行。

image.png

过程抽象:将类似“一个函数只执行一次”的需求剥离出来的过程。

6. 高阶函数使用模式

高阶函数(HOF):以函数作为参数,以函数作为返回值,常用作为函数装饰器。运行后会返回一个新的函数。

image.png

常用高阶函数:Once、Throttie、Debounce、Consumer/2、Iterative。

  • Throttie:节流函数,频繁触发的事件(鼠标移动,scroller滚动等)在一定时间内只触发一次,限制了触发频率。

原理:当时间还没到500毫秒时,timer的值为time,直到500毫秒后setTimeout使得timer为null,执行一次。

image.png

  • Debounce:防抖函数,例如输入中时,内容变化的时候不不保存,当一段时间内没有输入的时候再保存所输入的信息;以及下例中,鼠标运动的时候小鸟不会跟随,当鼠标停止运动时才会飞到鼠标所在位置。

原理:频繁触发事件时,会频繁执行clearTimeout(timer),直到100毫秒内没有触发,才执行一次。

image.png

  • Consumer:每隔一段时间执行一次。

原理:每调用一次,就向tasks数组中push一次,每1000毫秒取出并执行一次,然后clearInterval清空计时器,重新计时,直到下次到时间再次执行。

image.png

  • Iterative:可迭代方法。liL:nth-child(2n+1)为取出列表中的单数项。

原理:如果对象可迭代,就将对象内的每一项在执行后放入ret数组,然后返回执行完毕的ret数组,若不可迭代则单次执行。

image.png

纯函数:行为可预期的,结果固定的函数。

非纯函数:例如函数内执行return idx++,返回值与调用次数有关,无法确定准确的返回值。

高阶函数是纯函数,使用高阶函数减少非纯函数量,提高库里的纯函数比例,可以使得库更好维护。

7. JavaScript 编程范式

命令式:更强调怎么做,将具体做法写出来。

声明式:更强调做什么。定义一个函数,函数实现过程,然后调用函数。比命令式更简洁。

image.png

命令式案例:使用if else根据当前状态判断需要执行的操作。

image.png

声明式案例:toggle高阶函数会接收一系列action,当触发时,会执行将当前第一个action取出,然后push到最后一个,并执行该action。

image.png

比起命令式,声明式的方法更方便修改,只需要添加一个新的状态即可,因此具有更强的可拓展性。

三、课后个人总结:

通过该课程,我了解了JavaScript 好代码的标准,以及实现HTML/CSS/JS 各司其责的重要性,学会了组件的定义解析及特征以及组件封装基本方法。懂得了过程抽象的概念以及它的用途,明白了高阶函数使用模式以及JavaScript的两种编程范式。