<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,}遍