写好JavaScript三大原则 — 过程抽象 | 青训营笔记

210 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

写好JavaScript的一些原则:

  • 各司其职(让HTML、CSS和JavaScript职能分离)
  • 组件封装(好的UI组件具备正确性、扩展性、复用性)
  • 过程抽象(应用函数式编程思想)

什么是过程抽象 ?

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

在过程抽象当中我们可以把函数可以看成一个输入和输出的黑盒,在这个过程之中我们可以去做函数过程本身的一些抽象,用来实现一些通用性解决方案。

更通俗的理解我们可以将过程抽象想象成一个房间,房间里的门、窗、和房间空间本身都是数据,但当我们要门或者窗时的这个动作或行为本身是一个过程,也就说我们不仅将将数据进行抽象,这个过程也是可以进行抽象的。

案例:操作次数限制

  • 一些异步交互
  • 一次性的HTTP请求

下面有这样一段代码,每次点击时,会有2s的延时动画随后移除该Dom节点,但是如果用户在该节点还没有完全移除之前又点击了几次,则会报错(Dom节点不存在)。

const list = document.querySelector('ul');
const buttons = list.querySelectorAll('button');
buttons.forEach((button)=>{
    button.addEventListener('click', (evt) => {
        const target = evt.target;
        target.parentNode.className = 'completed';
        setTimeout(()=>{
            list.removeChild(target.parentNode);
        },2000);
    })
})

原因:当我们在2s内再次点击时,DOM元素还存在,所以还会触发定时器执行removeChild,但是元素只能被移除一次,所以会报错。

解决方法:我们可以对这个事件的执行次数做限制,让其只在第一次触发的时候执行。这里可以抽象出一个高阶函数once。该函数的参数为一个函数,返回值也为一个函数,在返回的函数中判断传入过来的函数是否存在,如果存在则执行该函数,然后将该函数赋值为null这样下次就不会再执行该函数了

function once(fn) {
    return function(...args) {
        if(fn) {
            const ret = fn.apply(this, args);
            fn = null;
            return ret;
        }
    }
}
const list = document.querySelector('ul');
const buttons = list.querySelectorAll('button');
buttons.forEach((button)=>{
    button.addEventListener('click', once((evt) => {
        const target = evt.target;
        target.parentNode.className = 'completed';
        setTimeout(()=>{
            list.removeChild(target.parentNode);
        },2000);
    }))
});

为了让 ”只执行一次“ 的需求覆盖不同的事件处理,我们将这个需求剥离出来,这个过程就称之为 过程抽象

高阶函数 :

定义:

  • 以函数作为参数
  • 以函数作为返回值
  • 常用于作为函数装饰器

funtion HOF(fn) {
    return function(...args) {
        return fn.apply(this, args);
    }
}

常用的高阶函数:

  • Once
  • Throttle 节流函数
  • Debounce 防抖函数
  • Consumer / 2
  • Iterative

思考: 为什么要使用高阶函数?

这里又了解到一个新的概念:

纯函数

定义:如果一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用则称该函数为纯函数;

使用纯函数是非常可靠的,并且不会对外界产生影响,在多人开发时能够方便进行单元测试,减少系统中非纯函数的数量,从而使得系统可靠性增加。