一种基于过程抽象的编程方式,在函数式编程中,函数就是一个管道(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)));
用勾股定理简单解释了函数的合成,虽然写复杂了,但是可以清楚的解释函数合成以及柯里化的原理。
函数编程的优点