今年JS最大的热点恐怕就是函数式编程了,不管是像我这种小菜鸟还是大佬们都在议论纷纷。我自己呢,通过网上合理冲浪也学习到了一些函数式编程的理念以及看法。
首先在目前个人从各方面学习到的知识得出:JS是不可能实现完全的函数式编程的,但是在JS当中函数也是一等公民,所以我们大可不必深究所谓的函数式细则,不同国家都有不同国情 何况是语言呢?取长补短 我们只需利用函数时编程的一些理念进行开发即可。
函数式编程中有一个非常重要的概念叫纯函数,JavaScript符合函数式编程的范式,所以也有纯函数的概念
那么什么是纯函数呢?
总结如下:
- 确定的输入 一定会返回确定的输出
- 函数在执行过程中,不能产生副作用
我们直接用Array中的方法进行举例子
Array.slice 在执行过程中,只要有确定的输入 ,它永远都会返回确定的输出结果 且不会改变原数组本身,所以slice是个纯函数实现
Array.splice 在执行过程中,虽然在确定的输入,它也会返回确定的输出,但是对原数组进行了修改,产生了副作用。所以他不能称为纯函数。
上文输出的纯函数概念到底有什么好处呢? 好处就一句话,我们可以安心的编写,放心的用。熟悉react的朋友,react虽然很灵活 但是一直有一条很严格的规则,React中就要求我们无论是函数还是class声明一个组件,这个组件都必须像纯函数一样,保护它们的props不被修 改。
JS的函数式编程还有一个重要概念 就是柯里化
柯里化的解释 维基百科中就描述的非常清除了:是把接收多个参数的函数,变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参 数,而且返回结果的新函数的技术就称为柯里化
柯里化的作用就是逻辑复用和让各个函数分工明确 让一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个 函数来处理
// 普通函数
function add (a, b, c) {
return a + b + c
}
add(1,2,3)
// 柯里化
let add = (a) => (b) => (c) => a + b + c
add(1)(2)(3)
// 自动柯里化函数
function currying(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args)
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2))
}
}
}
}
function add(a, b, c) {
return a + b + c
}
let sum = currying(add)(1, 2)(3)
console.log("sum", sum)
组合函数是在JavaScript开发过程中一种对函数的使用技巧
比如我们现在需要对某一个数据进行函数的调用,执行两个函数fn1和fn2,这两个函数是依次执行的; 那么如果每次我们都需要进行两个函数的调用,操作上就会显得重复;
可以将这两个函数组合起来,自动依次调用呢
// 组合函数
function compose(...fns) {
const length = fns.length
for (let i = 0; i < length; i++) {
if (typeof fns[i] !== "function") {
throw new TypeError("expected are function")
}
}
return function(...args) {
let index = 0
let result = length ? fns[index].apply(this, args) : args
while (++index < length) {
result = fns[index].call(this, result)
}
return result
}
}
function add(a) {
return a + 1
}
function double(a) {
return a * a
}
let foo = compose(add, double)(5)
console.log(foo)