1:纯函数和副作用
纯函数、副作用的内涵
纯函数(Pure Function)——输入输出数据流全是显式(Explicit)的函数 (入参为显示输入数据流,返回值为显示输出数据流)
纯函数——输入只能够以参数形式传入,输出只能够以返回值形式传递,除了入参和返回值之外,不以任何其它形式和外界进行数据交换的函数
纯函数/非纯函数的辨析
从数据流的角度理解“纯”与“不纯”的本质
纯函数只能有横向数据流 即 输入->操作过程->输出
如果有打印(console.log)或者输出(网络请求)等与外界的数据交互,则会变得不纯
纯函数解决了什么问题纯函数之所以能解决很多小问题,归根结底是因为他解决了两个大问题,'副作用',和'不确定性'
什么是纯函数?
同时满足以下两个特征的函数,我们就认为是纯函数:
对于相同的输入,总是会得到相同的输出
在执行过程中没有语义上可观察的副作用。
纯函数的这些规则并不是为了约束而约束,而是为了追求更高的确定性;同时引导我们做更加合理的逻辑分层,写出更加清晰、更善于应对变化的代码。
(纯函数不能对外界产生影响)即不能console.log()
纯函数不能发送网络请求(网络请求返回的内容往往是动态的,无法保证相同的输入有相同的输出)
什么是副作用?
在计算机科学中,函数副作用指当调用函数时,除了返回可能的函数值之外,还对主调用函数产生附加的影响。 ——维基百科
console.log() 会在控制台打印一行文字,这改变了浏览器的控制台,属于对外部世界的影响,也就是说 processName 函数在执行过程中产生了副作用。
2:const的理解
不可变数据实践指南:
1:const的理解const只能保证值类型的数据不变,而无法保证引用类型数据不变
如:const a=1a=2 不行,(1为number数字类型,为值类型),const无法重新赋值
const a={a:1} const b=a b.a=3(a的值同样发生改变,引用类型改变)
在函数式编程中,尽量用...拷贝引入的数据,这样可以避免修改原数据
3:不可变数据
不可变数据 (Immutable Data )就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是持久化数据结构( Persistent Data Structure),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的s性能损耗,Immutable 使用了 结构共享(Structural Sharing),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。
它的原理等同于git commit的原理,git 中文件快照功能修改的其实是改变的文件的索引(创建一个新文件,旧版本指向旧文件,新版本指向新文件,其他文件不变)
当你创建一个对象并修改他的时候,其实改的是他中间的某一个字段,其他的没有改变
在函数式编程中,逐层的浅拷贝远优于暴力拷贝(深拷贝)
一条数据有十层
如只需要修改第二层的数据,逐层浅拷贝就不会到更深层次
4:链式调用
// 多个工序的处理函数可以写为
const sum = arr.filter(biggerThan2).map(multi2).reduce(add, 0)//这种流水线形态,来处理数据,防止函数遭到外部变量的干扰,这种就叫链式调用
链式调用虽然牛,可它不是万金油。
map()、reduce()、filter() 这些方法之间,之所以能够进行链式调用,是因为:
它们都挂载在 Array 原型的 Array.prototype 上
它们在计算结束后都会 return 一个新的 Array
既然 return 出来的也是 Array,那么自然可以继续访问原型 Array.prototype 上的方法
也就是说,链式调用是有前提的。
链式调用的本质 ,是通过在方法中返回对象实例本身的 this/ 与实例 this 相同类型的对象,达到多次调用其原型(链)上方法的目的。
要对函数执行链式调用,前提是函数挂载在一个靠谱的宿主 Object 上。
5:偏函数和克里化
偏函数和柯里化解决的最核心的问题有两个,分别是:
1.函数组合链中的多元参数问题
2.函数逻辑复用的问题
函数参数里的“元数”,指的其实就是函数参数的数量。
在数学里,我们管只包含一个自变量的函数方程式叫“一元函数”,
y = x + 1
y = f(x)
相应地,包含两个自变量的函数方程式就叫二元函数
z = x + y
z = f(x, y)
类比到 JS 函数里来说,单个入参的函数就是一元函数
function double(x) {
return x*2
}
两个入参的函数就是二元函数
function add(x, y) {
return x+y
}
显然,“多元函数”指的就是有多个(n个)入参的函数
function multiple(x,y........n) {
return ....
}
概念:
任何时候,只要我们想要对函数的入参数量进行改造,必须先想到偏函数&柯里化。
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
通俗来讲,它是这个意思: 柯里化是把 1 个 n 元函数改造为 n 个相互嵌套的一元函数的过程。
再具体一点,就是说柯里化是一个把 fn(a, b, c)转化为fn(a)(b)(c)的过程
偏函数是指通过固定函数的一部分参数,生成一个参数数量更少的函数的过程。
下面是代码:
这是最简单的克里化和偏函数的例子,用于帮助大家理解