很多语言是聚范式/多重范式编程,即支持多在编程范式,如面向对象(Java),面向过程(C语言),泛函(函数式),元程序设计等;以下例子都用 JavaScript 举例;
命令式编程(Imperative)
如命令一般指导程序一步步完成功能,如 for 循环:
1 2 3 4 5 6 7
| function myFn(n) { for (i = 0; i < 3; i++) { n++; } console.log(n); } myFn(0);
|
函数式编程/声明式(Functional/Declarative)
函数式编程特点:
- 函数式编程是声明式的;
- 提倡纯函数理念,变量私有,不同于面向对象编程的成员共享;
- 无副作用,不影响其他外部变量;
- 有些类似初中数学纯函数f(x)的定义,提供输入值,返回新的输出值,每次提供相同输入值总能返回相同输出值,使线程安全可靠;
1 2
| Array.map(); Math.random();
|
- 函数的大量使用,变量中存储函数,动态创建函数,返回值为函数,函数作为参数传递,等等;
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 34 35
| var myStr = function(){return 'Hello World'}; console.log(myStr);
var myObj = { name: 'Cloud', getName: function(){ return this.name; } } console.log(myObj.getName());
console.log('Hello ' + (function(){ return 'World'; })());
function paraFn() { return 'Hello'; } function myFn(a, b) { return a + b; } console.log(myFn(paraFn(), 'World'));
function myFn2() { var a = 'Hello '; return function(){ return a + 'World'; } } console.log(myFn2()());
|
总结:例如for循环一个数组,命令式便是写出具体循环的方式,声明式便是只写声明函数,只要循环结果,具体方式交给程序执行;
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var a = [1, 2, 3]; var b = []; for (i = 0; i < 3; i++) { b.push(a[i] * a[i]); } console.log(b);
var a = [1, 2, 3]; var b = a.map(function(i){ return i * i; }); console.log(b);
|
同样的结果,代码量和理解难易上,声明式都明显优于命令式对吧;
声明式编程:
特点:
递归实现阶乘便是一个典型的函数式:
1 2 3 4 5
| function factorial(n) { if (n == 0) return 1; return n * factorial(n-1); } console.log(factorial(3));
|
**.map() .reduce()**等 也是申明式编程函数;
函数合成
一个值变成另一个值,中间经过多个函数,将多个函数合并为一个函数来实现;
举个例子:
1 2 3 4 5 6
| // 高中数学常见的过程 g(x) = 2x; h(x) = x + 3; f(x) = 2x + 3; // 则可变换为以下形式,即我们所学的复合函数 f(x) = h(g(x));
|
上面的f(x)**便是一个合成函数,实现了变量x到2x + 3**的转变;
js的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13
| function gFn(x) { return x *2; } function hFn(x) { return x + 3; } console.log(hFn(gFn(1)));
function fFn(x) { return hFn(gFn(x)); } console.log(fFn(1));
|
函数柯理化(Currying)
以逻辑学家**Haskell Curry**命名,即使接收多个参数的函数变成接受单个参数的函数的过程。单参数会使函数合成更简单;
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function plusFn(x, y, z) { return x + y + z; } console.log(plusFn(1, 2, 3));
function plusFn(x) { return function(y) { return function(z) { return x + y + z; } } } console.log(plusFn(1)(2)(3));
|