# 1.提炼函数

# 好处:

避免出现超大函数。 独立出来的函数有助于代码复用。 独立出来的函数更容易被覆写。 独立出来的函数如果拥有一个良好的命名,它本身就起到了注释的作用。 语义化将多段分离的逻辑放在不同的函数中实现,可以使代码逻辑清晰,清楚的看到每一步在做什么。

# 代码举例:

实现获取数据,然后操作dom显示数据,最后添加事件

  • 函数提炼前
// 逻辑都写在一起,需要将所有逻辑看完才知道这段代码是干嘛的,局部逻辑无法复用
function main() {
    $.ajax.get('/getData').then((res) => {
        const ul = document.getElementById('ul');
        ul.innerHTML = res.list.map(text => `<li class="li">${text}</li>`).join('\n');
        const list = document.getElementsByClassName('li');
        for (let i = 0; i < list.length; i ++) {
            list[i].addEventListener('focus', () => {
                // do something
            });
        }
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 函数提炼后
    function getData() {
      return $.ajax.get('/getData').then((res) => res.data.list);
      }
      function showList(list) {
          const ul = document.getElementById('ul');
          ul.innerHTML = list.map(text => `<li class="li">${text}</li>`).join('\n');
      }
      function addEvent() {
          const list = document.getElementsByClassName('li');
          for (let i = 0; i < list.length; i ++) {
              list[i].addEventListener('focus', () => {
                  // do something
              });
          }
      }
      // 逻辑清晰,一眼读懂每一步在做什么,某些提炼出来的函数还可以被复用
      async function main() {
          const list = await getData(); // 获取数据
          showList(list); // 显示页面
          addEvent(); // 添加事件
      }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

# 2. 纯函数

纯函数是指不依赖于且不改变它作用域之外的变量状态的函数。 纯函数的返回值只由它调用时的参数决定,它的执行不依赖于系统的状态(执行上下文)。 相同的输入参数,一定会得到相同的输出,也就是内部不含有会影响输出的随机变量。

# 不属于纯函数的特点:
  • 更改文件系统
  • 往数据库插入记录
  • 发送一个 http 请求
  • 可变数据
  • 打印/log
  • 获取用户输入
  • DOM 查询
  • 访问系统状态

# 纯函数的作用:

可靠性:函数返回永远和预期一致

可缓存性:因为只要输入一样输出一定一样,因此可将输入作为key,输出作为值,使用对象缓存已经计算的结果

可移植性:因为没有外部依赖,所以移植到任何环境都可正确运行

可测试性:方便针对函数做单元测试

可并行性:对一些复杂计算,可以并行计算(例如使用nodejs多个子进程同时并行计算多个任务,提高计算速度)

# 应用场景:
  • 工具函数最好使用纯函数
  • 多平台使用的代码(nodejs、浏览器、微信小程序、native客户端等)
  • 相对独立的功能
    var a = 1;
    // 非纯函数
    function sum(b) {
        return a + b;
    }
    // 非纯函数
    function sum(b) {
        a = 2;
        return b;
    }
    // 非纯函数
    function sum(b) {
        return b + Math.random();
    }


    // 纯函数
    function sum (b, c) {
        return b + c;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3.剩余参数

function sum(...args) {}
// 剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
1
2

参考链接

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters

# 4.通过参数默认值强制要求传参

ES6 指定默认参数在它们被实际使用的时候才会被执行,这个特性让我们可以强制要求传参:

/**
* Called if a parameter is missing and
* the default value is evaluated.
*/
function mandatory() {
    throw new Error("Missing parameter");
}
function foo(mustBeProvided = mandatory()) {
    return mustBeProvided;
}
1
2
3
4
5
6
7
8
9
10

函数调用 mandatory() 只有在参数 mustBeProvided 缺失的时候才会被执行。

在控制台测试:

foo() Error: Missing parameter foo(123) 123