js 函数式编程
函数式的思想, 就是不断地用已有函数, 来组合出新的函数。
函数式编程具有五个鲜明的特点:
1. 函数是"第一等公民"
指的是函数与其他数据类型一样,处于平等地位
2. 只用"表达式",不用"语句"
"表达式"(expression)是一个单纯的运算过程,总是有返回值;
"语句"(statement)是执行某种操作,没有返回值。
3. 没有"副作用"
指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),
产生运算以外的其他结果。
4. 不修改状态
变量往往用来保存"状态"(state)。不修改变量,意味着状态不能保存在变量中,
函数式编程使用参数保存状态
5. 引用透明
指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,
引用函数所得到的返回值总是相同的
函数式编程的意义:
1. 代码简洁,开发快速
2. 接近自然语言,易于理解
3. 更方便的代码管理
4. 易于"并发编程"
5. 代码的热升级
---------------------分割线------------------------
在 JavaScript 中,函数本身为一种特殊对象,属于顶层对象,
不依赖于任何其他的对象而存在,因此可以将函数作为传出 / 传入参数,
可以存储在变量中,可以做一切其他对象可以做的事情。
自调用函数(递归--自己调用自己)实际上是高阶函数的一种形式。
函数式编程示例:
// 阶乘的一般实现 function factorial(n) { if (n == 1) { return 1; } else { return factorial(n - 1) * n; } } // 阶乘的函数式编程风格实现 function mul(a, b){ return a*b; } function dec(x){ return x - 1; } function equal(a, b){ return a==b; } function factorial(n) { if (equal(n, 1)) { return 1; } else { return mul(n, factorial(dec(n))); } }---------------------分割线------------------------
//加法 function adder(num) { return function(x) { return num + x; } } var add5 = adder(5); var add6 = adder(6); console.log(add5(1));// 6 console.log(add6(1));// 7这里的add5表示的函数可以解决基数为5的加法问题,只需要传递一个参数就可以了,
//计算m的n次方 var powerOfN = function(n){ return function(m){ var res = 1; for(var i = 0; i < n; ++i){ res *= m; } return res; } ; }; //按需生成 var powerOf2 = powerOfN(2); var powerOf3 = powerOfN(3); //调用传参 console.log(powerOf2(3)); console.log(powerOf3(2));柯里化通用实现:
function curry(fn) { var args = [].slice.call(arguments, 1); return function() { var inargs = [].slice.call(arguments); console.log(args.concat(inargs)); return fn.apply(null, args.concat(inargs)); } } function curry(fn) { var args = [].slice.call(arguments, 1); return function() { var inargs = [].slice.call(arguments); console.log(args.concat(inargs)); return fn.apply(null, args.concat(inargs)); } } function add(num1, num2) { return num1 + num2; } var newAdd = curry(add, 5); console.log(newAdd(6));柯里化将降低了函数使用的普遍性,增加了使用的特异性,使用柯里化需要认真识别
function foo(f, g) { return function() { return f.call(null, g.apply(null, arguments)); //return f(g.apply(null, arguments)); 也是可以的 } } var sum = function(x, y) { return x + y; } var square = function(x) { return x * x; } var squareofsum = foo(square, sum); squareofsum(2, 3);// 25下面我们来看一下怎样从过程式编程过渡到函数式编程的:
1>形式一
var sum = function(x, y) { return x + y; } var square = function(x) { return x * x; } function foo(){ return square( sum(2, 3) ); } foo();// 252>形式二
var sum = function(x, y) { return x + y; } var square = function(x) { return x * x; } function foo(f, g){ return f( g(2, 3) ); } foo(square, sum);// 253>形式三
var sum = function(x, y) { return x + y; } var square = function(x) { return x * x; } function foo(f, g){ return function(){ var num1 = arguments[0]; var num2 = arguments[1]; console.log(num1, num2);// 2 3 var temp = g(num1, num2); console.log(temp);// 5 return f(temp); }; } var myfunc = foo(square, sum); myfunc(2, 3);// 254>形式四
var sum = function(x, y) { return x + y; } var square = function(x) { return x * x; } function foo(f, g){ return function(){ var temp = g.apply(null, arguments); return f(temp); }; } var myfunc = foo(square, sum); myfunc(2, 3);// 25最后的形式四就是我们想要得到的效果。
---------------------分割线------------------------
其他示例:
1>
function foo(fn, array, value){ var res = array.map(function(ele){ return fn.apply(null, [ele].concat(value)); }); return res; } function add(x, y) { return x + y; } function sub(x, y) { return x - y; } console.log( foo(add, [1, 2, 3], 3) );// [4, 5, 6] console.log( foo(sub, [1, 2, 3], 3) );// [-2, -1, 0]
function multicast(fn) { return function (){ var pre = arguments[0]; var rest = arguments[1]; var ret = pre.map(function(ele) { return fn.apply(this, [ele].concat(rest)); }); return ret; } } function add(x, y) { return x + y; } var newAdd = multicast(add); console.log(newAdd([1,2,3],3));// [4, 5, 6] function sub(x, y) { return x - y; } var newSub = multicast(sub); console.log(newSub([1,2,3],3));// [-2, -1, 0]
参考资料:
https://blog.oyanglul.us/javascript/functional-javascript.html
http://www.phodal.com/blog/javascript-higher-order-functions/
http://www.cnblogs.com/wing011203/archive/2013/07/07/3176641.html
http://www.ibm.com/developerworks/cn/web/1006_qiujt_jsfunctional/
http://www.cnblogs.com/pigtail/p/3447660.html
http://www.ruanyifeng.com/blog/2012/04/functional_programming.html
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u011700203/article/details/47189363