函数式编程,是一种编程规范
编程规范
-
面向过程
先做这个,再做那个,然后做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 = 123;
let 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;