函数式编程 Javascript的箭头函数 ECMAScript2015
引入箭头表达式。箭头函数其实是匿名函数,基本语法如下:
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// 等于 : => { return expression; }
// 只有一个参数时,括号才可以不加:
(singleParam) => { statements }
singleParam => { statements }
//如果没有参数,就一定要加括号:
() => { statements }
示例:
1 2 3 4 5 6 7 8 9 10 var simple = a => a > 15 ? 15 : a;simple(16 ); simple(10 ); let max = (a, b ) => a > b ? a : b;var arr = [5 , 6 , 13 , 0 , 1 , 18 , 23 ];var sum = arr.reduce((a, b ) => a + b); var even = arr.filter(v => v % 2 == 0 ); var double = arr.map(v => v * 2 );
有些时候,某些函数在声明的时候就是调用的时候,尤其是函数式编程中,一个函数还对外返回函数的时候。
1 2 3 4 5 6 7 8 9 10 11 function MakePowerFn (power ) { return function PowerFn (base ) { return Math .pow(base, power); } } power3 = MakePowerFn(3 ); power2 = MakePowerFn(2 ); console .log(power3(10 )); console .log(power2(10 ));
用箭头函数
1 2 3 4 5 6 7 8 9 10 11 12 13 MakePowerFn = power => { return base => { return Math .pow(base, power); } } MakePowerFn = power => base => Math .pow(base, power) MakePowerFn = (power ) => ( (base) => (Math .pow(base, power)) )
匿名函数的递归 函数式编程立志于用函数表达式来消除有状态的函数,以及for/while循环,所以在函数式编程里不应该用for/while循环,而要改用递归(递归的性能很差,所以,一般用尾递归来做优化,也就是把函数的计算状态当参数一层一层往下传递,这样语言的编译器后解释器就需要用函数栈来帮你保存函数的内部变量的状态了)。
递归的代码就是函数自己调用自己,比如求阶乘
1 2 3 function fact (n){ return n == 0 ? 1 : n * fact(n-1 ); }
对于匿名函数,可以把匿名函数当成一个参数传给另外一个函数,因为函数的参数有名字,所以就可以调用自己了。
1 2 3 4 5 6 function combinator(func ) { func (func ) ; } (func ) => (func (func ) )
阶乘代码重构1 2 3 4 5 6 7 8 9 10 11 12 13 funtion fact(func , n ) { return n == 0 ? 1 : n * func (func , n-1 ) ; } var fact = (func , n ) => (n == 0 ? 1 : func (func , n-1 ) );fact(fact, 5 ) (func , x ) => func (func , x) ( (func , n ) => ( n ==0 ? 1 : n * func (func , n-1 ) ), 5 );
动态高级函数的递归 递归版高阶函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 HighOrderFact = function(func ) { return function(n){ return n == 0 ? 1 : func (func ) (n-1) ; }; } // 需要一个函数做参数,然后返回这个函数的递归版本 fact = HighOrderFact (HighOrderFact) ;fact (5) ;HighOrderFact (HighOrderFact) (5) ;fact = function (hifunc) { return hifunc(hifunc); }( function(func ) { return function(n){ return n == 0 ? 1 : n * func (func ) (n-1) ; }; } ); // 调用 fact (5) ;// 箭头函数重构 fact = (highfunc => highfunc(highfunc) ) ( func => n => n == 0 ? 1 : n * func (func ) (n-1) );
重构之前的程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function find (x, y) { for (let i = 0 ; i< x.length; i++){ if (x[i] == y) return i; } return null; } funcion find (x, y, i=0 ){ if ( i >= x.length) return null; if ( x[i] == y) return i; return find (x, y, i+1 ); } ((func , x , y , i ) => func (func , x,y i) ) ( (func , x , y , i =0) => ( i>= x.length ? null : x[i] == y ? i : func (func , x, y, i+1 ) ), arr, 2 ) const find = (highfunc => highfunc(highfunc))( func => (x, y, i =0 ) => ( i >= x.length ? null : x[i] == y ? i : func (func ) (x, y, i+1 ) ) ) ;
可以参考以下两篇文章