JS函数式编程基础(FP)

一种基于过程抽象的编程方式,在函数式编程中,函数就是一个管道(pipe)。这头进去一个值,那头就会出来一个新的值,没有其他作用

在函数式编程中,函数被看做是“一等公民”。JavaScript可以通过巧妙地函数组合来构建抽象,通过内嵌函数的方式,在软件开发的过程中,我们关心的是“函数要做什么”,而不是“函数如何做”的问题

1.函数必须是纯的,不能有副作用,一个函数如果输入参数确定,如果输出结果是唯一确定的,那么它就是纯函数。

function setcolor(el,color){
    el.style.color=color;
}
 function setcolors(els,color){
    Array.from(els).map(el => setcolor(el,color));
 }
setcolors(document.querySelectorAll('#lu li'),'red');

setcolor()函数中操作DOM,它不是一个纯函数,setcolors()虽然没有直接操作DOM,但是函数里面调用了setcolor,所以它也不是一个纯函数。
高阶函数过程抽象提高函数纯度

function setcolor(el,color){
    el.style.color=color;
}

function __multi__(fn){
    return function(arrayLink,...args){
        return Array.from(arrayLink).map(item => fn(item,...args));
    }
}

var setcolors=__multi__(setcolor);
setcolors(document.querySelectorAll('#lu li'),'red');

multi高阶函数实际是对fn进行一个变化,当传入的第一个操作数是arrayLink时,就会对这个arrayLink的每一个元素执行fn操作,这样做可以简化操作的过程

其实,封装的multi函数的作用就是做批量处理,还有很多的用途,比如:

function __multi__(fn){
    return function(arrayLink,...args){
        return Array.from(arrayLink).map(item => fn(item,...args));
    }
}
function add(x,y){
    return x+y;
}
var m_add=__multi__(add);
console.log(m_add([1,2,3],3));   //[4,5,6]

此时m_add()函数不用考虑传入的参数,multi函数会将参数进行转换。

规约函数

function reduce(fn,...args){
    return args.reduce(fn);
}
function add(x,y){
    return x+y;
}
console.log(reduce(add,1,2,3));

reduce函数通过重复调用一个函数,将数组转换为单一的值

2.函数的柯里化(普及知识:柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术)

var add=(x,y) => x+y;

//简单加法的柯里化:
var add=function(x){
    return function(y){
        return x+y;
    }
}

事实上柯里化是一种“预加载”函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上讲,这是一种对参数的“缓存”。说白了就是把一个多参数的函数,转化为单参数函数

3.函数组合
有了纯函数且柯里化之后,就可以进行函数组合了

//函数合成
var compose=function(f,g){
    return function(x){
        return f(g(x));
    }
}
//柯里化
var add=function(x){
    return function(y){
        return Math.pow(x,2)+Math.pow(y,2);
    }
}
var sqrt=function(a){
    return Math.sqrt(a);
}
console.log(sqrt(add(3)(4)));

用勾股定理简单解释了函数的合成,虽然写复杂了,但是可以清楚的解释函数合成以及柯里化的原理。

函数编程的优点

  • 单元测试:函数求值的结果只是其返回值,而惟一影响其返回值的就是函数的参数。 对被测试程序中的每个函数,你只需在意其参数,而不必考虑函数调用顺序,不用谨慎地设置外部状态。所有要做的就是传递代表了边际情况的参数
  • 并行:函数式程序里没有任何数据被同一线程修改两次,更不用说两个不同的线程了,不用担心死锁和临界区,函数式程序无需任何修改即可并行执行

你可能感兴趣的:(JS函数式编程基础(FP))