如何写好JavaScript | 青训营笔记

56 阅读3分钟

如何写好JavaScript | 青训营笔记

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

1.写好js的一些原则

(1)各司其职:html,css,js各干各的工作,让HTML、css和js的只能分离开来

①html/css/js各司其职

②应当避免不必要的由js直接操作样式

③可以用class来表示状态

④纯展示类交互寻求零JS方案

(2)组件封装:一个好的UI组件应该具备正确性、扩展性、复用性。

组件是指web页面上抽出来一个个包含模板(html)、功能(JS)、样式(CSS)的单元。

基本方法

  • 组件设计的原则:封装性、正确性、扩展性、复用性

  • 实现组件的步骤:

    1、结构设计

    2、展现效果

    3、行为设计:

    • API (功能)
    • Event (控制流)
  • 三次重构

    1. 插件化:解耦

      • 将控制元素抽取成插件
      • 插件与组件之间通过依赖注入方式建立联系
    2. 模板化:解耦

      • 将HTML模板化,更易于扩展
    3. 抽象化(组件框架):抽象

      • 将组件通用模型抽象出来

(3)过程抽象:应用函数式编程思想。

过程抽象是⽤来处理局部细节控制的⼀些⽅法,是函数式编程思想的基础应⽤。

同时为了让某个需求覆盖不同的事件处理,我们可以将这个需求剥离出来,也就是过程抽象

//只点一次
function once(fn) {
  return function (...args) {
    if (fn) {
      const ret = fn.apply(this, args);
      fn = null;
      return ret;
    }
  };
}
​
buttons.forEach((button) => {
  button.addEventListener('click', once((evt) => {
    const target = evt.target;
    target.parentNode.className = 'completed';
    setTimeout(() => {
      list.removeChild(target.parentNode);
    }, 2000);
  }));
});

2、高阶函数

首先我们要了解纯函数:

a.相同输入返回相同输出

b.无副作用

c.不依赖于外部状态

一个函数不依赖于上下文,不管什么时候调用,调用多少次,只要输入相同,输出就是相同的,这样的函数就是纯函数

高阶函数都是纯函数

比如:

// 纯函数
function add(a, b) {
  return a + b;
}
// 非纯函数
let a = 6;
function add(b) {
  return a + b;
}

Higher-Order Function中有一个等价范式HOF0,调用fnHOF0(fn)是完全等价的,其他的高阶函数都是基于这个范式做了一些拓展:

常见的高阶函数:

1、节流 Throttle

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

function throttle(fn, time = 500) {
  let timer;
  return function (...args) {
    if (timer == null) {
      fn.apply(this, args);
      timer = setTimeout(() => {
        timer = null;
      }, time)
    }
  }
}

2、防抖 Debounce

function debounce(fn, dur) {
  dur = dur || 100;
  var timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, dur);
  }
}

3、consumer

function consumer(fn, time) {
  let tasks = [],
      timer;
  return function (...args) {
    tasks.push(fn.bind(this, ...args));
    if (timer == null) {
      timer = setInterval(() => {
        tasks.shift().call(this)
        if (tasks.length <= 0) {
          clearInterval(timer);
          timer = null;
        }
      }, time)
    }
  }
}

4、Iterative

function iterative(fn) {
  return function (subject, ...rest) {
    if (isIterable(subject)) {
      const ret = [];
      for (let obj of subject) {
        ret.push(fn.apply(this, [obj, ...rest]));
      }
      return ret;
    }
    return fn.apply(this, [subject, ...rest]);
  }
}

3、编程范式

命令式和声明式:

命令式编程的主要思想是关注计算机执行的步骤,一步一步告诉计算机先做什么再做什么,就是关注怎么做(How)。

声明式编程是以数据结构的形式来表达程序执行的逻辑,它的主要思想是关注做什么(What),但不指定具体要怎么做。

4、写代码最应该关注什么?

包括但不限于一下内容:

  • 风格
  • 效率
  • 约定
  • 使用场景
  • 设计