<html> <head> <meta charset="utf-8"> <title>javascript函数编程</title> <meta name="keyword" content="javascript函数编程"> <meta name="discription" content="javascript函数编程"> </head> <body> <script> javascript函数编程 第二章 一等公民的函数 用一个函数把另外一个函数包起来, 目的仅仅是延迟执行, 真的是非常糟糕的编程习惯. 第三章 纯函数的好处 好处: 1 纯函数是这样一种函数, 即相同的输入, 永远会得到相同的输出, 而却没有任何可观察的副作用; 2 使用纯函数的形式, 函数就能做到自给自足; 副作用: 1 在计算结果的过程中, 系统状态的一种变化, 或者与外部世界进行的可观察的交互 更新文件系统 往数据库插入数据 发送一个http请求 可变数据 打印 / log 获取用户数据 DOM查询 访问系统状态 追求 "纯" 的理由 1 可缓存性 var memoize = function(f) { var cache = {}; return function() { var arg_str = JSON.stringify(arguments); alert(arg_str); cache[arg_str] = cache[arg_str] || f.apply(f, arguments); return cache[arg_str]; } } var squreNumber = memoize(function(x) { return x * x; }) squreNumber(4); //16 2 可移植性 / 自文档化 3 可测试性 4 合理性 纯函数引用透明: 吐过一代代码可以替换成他执行所得的结果, 而且是在不改变整个程序行为的前提下替换的, 那么我们就说这段代码是引用透明的 并行代码在服务端js环境以及使用了web worker的浏览器那里是非常容易实现的, 因为使用了线程(thread). 不过出于对非纯函数复杂的奥绿, 当前主流观点还是避免使用这种并行 slice(); //保留原数组不变 splice(); //截取原数组,原数组改变 第四章 柯里化 curry 概念: 只传递函数一部分参数来调用它, 让他返回一个函数去处理剩下的参数. 可以一次性的调用curry函数, 也可以每次只穿一个参数分多次调用 function add(x, y) { return function(y) { return x + y; } } var a = add(1); a(2); //3 只传给函数一部分参数通常也叫做局部调用, 能够大量减少样板文件的代码 第五章 代码组合 var compose = function(f, g) { return function(x) { return f(g(x)); } } f, g都是函数, x式他们之间通过 "管道" 传输的值. var toUpperCase = function(x) { return x.toUpperCase(); } var exclain = function(x) { return x + "!"; } var shout = compose(exclain, toUpperCase) shout("Hello"); 范畴学: 是数学中的一个抽象分支, 能够形式化诸如集合论, 类型论, 群论, 以及逻辑学等数学分支中的一些概念. 范畴学主要处理的对象, 态射和变化式. 第六章 示例应用 与命令式不同, 声明式意味着我们要写表达式, 而不是一步一步的指示 //命令式 var makes = []; for (i = 0; i < cars.length; i++) { makes.push(cars[i].make) } //声明式 var makes = cars.map(function(car) { return car.make; }) //命令式的循环要求你必须先实例化一个数组,而且执行完成这个实例化语句之后,解析器才继续执行后面的代码 //命令式 var authenticate = function(form) { var user = toUser(form); return login(user); } //声明式 var authenticate = compose(login, touser); //虽然命令式的版本不一定就是错的,但是还是因编码了一种一步接着一步的执行方式. //而compose表达式只是简单的指出这么一个事实:用户验证是touser和login两个行为的 //组合.这再次说明,声明式为代码更新提供了支持,是的我的应用代码成为了一种高级规范 第七章 Hindley - Milner 类型签名 类型签名补单可以用于编译时检测, 还是最好的文档.所以类型签名在函数式编程中扮演着非常重要的角色 //strLength :: String ->Number var strLength = function(s) { return s.length; } //join:: String ->[String]->String var join = curry(fucntion(what, xs) { return xs.join(what); }) 第八章 特百惠 函数式程序: 通过管道吧数据在一系列纯函数之间传递的程序.这些程就是声明式的行为规范 var Container = function(x) { this.__value = x; } Container.of = function(x) { return new Container(x); } //Container 作为一个容器,Container.of作为构造器 第九章 Monad pointed functor 关于容器的of方法, 不是用老避免使用new关键字, 而是用来把值放到默认最小化上下文中的.of没有真的取代构造器 他是一个我们称之为pointed的重要接口的一部分 //这里关键是把任意的值丢到容器里然后开始导出使用map的能力 IO.of("tetris").map(concat("master")); //IO("tetris master"); Maybe.of(1336).map(add(1)); //Map(1337); Task.of([{ id: 2 }, { id: 3 }]).map(_.prop("id")); //Task([2,3]); 第十章 Applicative functor ap就是这样一种函数能够把一个functor的函数值应用到另一个functor的值上. Container.of(add(2)).ap(Container.of(3)); Container(5); //all togrther now Container.of(2).map(add).ap(Container.of(3)); //Container(5) //本例中的add是被map局部调用的,所以add必须是一个curry函数 Container.prototype.ap = function(other_container) { return other_container.map(this.__value); } </script> </body> </html>
总结:报告老板,在看懂之前我还能看{10,}遍