函数式编程

326 阅读2分钟

函数式编程,是一种编程规范

编程规范

  • 面向过程
    先做这个,再做那个,然后做xxx

  • 面向对象
    把功能组织成对象,然后相关操作作为对象的方法

  • 函数式编程
    把功能分解为一系列独立的函数,通过函数间相互调用来完成功能

为什么要用函数式编程

能提高复用性和可扩展性

每一个函数就是一块积木,能随时拼入新积木,随时取出积木复用
涉及到业务逻辑的代码,还是用面向对象,面向对象擅长组织逻辑,函数式编程可复用性好

完美贴合Tree-shaking

Tree Shaking 值的就是当我引入一个模块的时候,我不引入这个模块的所有代码,我只引入我需要的代码。

Tree-shaking的本质是消除无用的js代码。无用代码消除在广泛存在于传统的编程语言编译器中,编译器可以判断出某些代码根本不影响输出,然后消除这些代码,这个称之为DCE(dead code elimination)。

Tree-shaking是通过文档流的引入判断是否使用某个方法,但面向对象的编程方案无法记录这样一个文档流

如何写好函数式编程

函数式编程要求

保证纯函数

一个函数的返回结果只依赖于他的参数,同样的输入必定有同样的输出

let a = 10;
// 非纯函数, 依赖了一些外部数据,a的值不是函数能控制的,相同输入下不一定能得到相同的输出
function add(num) {
  return a + num;
}

// 纯函数, 虽然a也可能会变,但是是作为输入在变
function add(a, num) {
  return a + num;
}

减少函数的副作用

函数的副作用就是函数会影响外部的数据,如外部的全局变量

let a = 123let obj = {
  a: 123;
}
let arr = [1, 2, 3];
// 改变了外部的变量a,即有副作用
function aPlus(a) {
  a += 1;
  return a;
}

// 消除副作用
function aPlus(a) {
  a += 1;
  return a;
}
// 外部数据是引用类型, 拷贝后处理
function objPlus(obj) {
  let _obj = Object.create(obj);
  _obj.a += 1;
  return _obj;
}

function arrPlus(arr) {
  let _arr = [...arr];
  _arr[0] += 1;
  return _arr;
}

工程化下的函数式编程

函数式编程,写为模块化的规范

/* 传统的面向对象式,直接把类暴露出去 */
function class1() {
}
// es6编程规范
export default class1;
import class1 from "./model.js";
// commonjs
module.exports = class1;
const class1 = require("./model.js");

/* 函数式编程,一个个独立暴露 */
// es6
export function f1() {
}
export function f2() {  
}
import { f1 } from "./model.js";
import * as all from "./model.js";
// commonjs
function f1() {
}
function f2() {  
}
exports.f1 = f1;
exports.f2 = f2;
const all = require(./model.js);
const f1 = require(./model.js).f1;