js函数式编程

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>test</title>

<!-- <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> -->

</head>

<body>

<div class="testDiv">

<h1>编程思想</h1>

<p>

1,函数式编程;

2,面向对象编程(工厂,单例,观察者,发布订阅者等23中设计模式)

3,过程式编程

</p>

<ol>

<li>强调将计算过程分解成可复用的函数</li>

<li>只有纯的、没有副作用的函数,才是合格的函数</li>

<li>函数式编程只是范畴论的运算方法,跟数理逻辑、微积分、行列式是同一类东西,都是数学方法,只是碰巧它能用来写程序。</li>

<li>在函数式编程中,函数就是一个管道(pipe)。这头进去一个值,那头就会出来一个新的值,没有其他作用</li>

<li>没有磁盘读写,或者最大限度的减少磁磁盘读写,纯计算编程</li>

</ol>

<h1>函数式编程有<strong>两个最基本的运算</strong>:合成和柯里化。</h1>

<ol>

<li>如果一个值要经过多个函数,才能变成另外一个值,就可以把所有中间步骤合并成一个函数,这叫做"函数的合成"(compose)。</li>

<li>所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。</li>

<li>

<pre>

var checkage = min => (age => age > min);

var checkage18 = checkage(18);

checkage18(20);

</pre>


 

</li>

<li>这表明函数柯里化是一种“预加载”函数的能力,通过传递一到两个参数调用函数,就能得到一个记住了这些参数的新函数。从某种意义上来讲,这是一种对参数的缓存,是一种非常高效的编写函数的方法:</li>

<li>

<pre>

// 柯里化之前

function add(x, y) {

return x + y;

}

add(1, 2) // 3

// 柯里化之后

function addX(y) {

return function (x) {

return x + y;

};

}

addX(2)(1) // 3

</pre>

</li>

<li>

<h2>函子概念</h2>

<h3>函数不仅可以用于同一个范畴之中值的转换,还可以用于将一个范畴转成另一个范畴。这就涉及到了函子(Functor)</h3>

<h3>函子是函数式编程里面最重要的数据类型,也是基本的运算单位和功能单位</h3>

<h3>它首先是一种范畴,也就是说,是一个容器,包含了值和变形关系。比较特殊的是,它的变形关系可以依次作用于每一个值,将当前容器变形成另一个容器。</h3>

</li>

<li>

一般约定,函子的标志就是容器具有map方法。该方法将容器里面的每一个值,映射到另一个容器。

</li>

<h1>命令式编程和声明式编程</h1>

<ul>

<li>

<p>命令式代码:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。</p>

<p>声明式代码:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。</p>

<pre>

// 命令式

var makes = [];

for (var i = 0; i < cars.length; i++) {

makes.push(cars[i].make);

}

// 声明式

var makes = cars.map(function(car){ return car.make; });

</pre>

</li>

<li>函数式编程的一个明显的好处就是这种声明式的代码,对于无副作用的纯函数,我们完全可以不考虑函数内部是如何实现的,专注于编写业务代码。优化代码时,目光只需要集中在这些稳定坚固的函数内部即可。</li>

<li></li>

</ul>

 

</ol>


 

</div>

 

<script>

//假设我们需要对一个字符串做一些列操作,如下,为了方便举例,我们只对一个字符串做两种操作,

//我们定义了一个新函数shout,先调用toUpperCase,

//然后把返回值传给exclaim函数,这样做有什么不好呢?

//不优雅,如果做得事情一多,嵌套的函数会非常深,

 

//而且代码是由内往外执行,不直观,

 

//我们希望代码从右往左执行,这个时候我们就得使用组合。

// 函数的合成;

 

// 不优雅的例子

var toUpperCase = function(x) { return x.toUpperCase(); };

 

var exclaim = function(x) { return x + '!'; };

 

var shout = function(x){

return exclaim(toUpperCase(x));

};

shout("send in the clowns");

 

//=> "SEND IN THE CLOWNS!"

 

// 优雅的例子;

//定义compose

 

var compose = (...args) => x => args.reduceRight((value, item) => item(value), x);

 

var toUpperCase = function(x) { return x.toUpperCase(); };

var exclaim = function(x) { return x + '!'; };

var exclaim222 = function(x) { return x + '7777777'; };

 

shout("send in the clowns");

//=> "SEND IN THE CLOWNS!"

//函数

var add = function(x) {

return function(y) {

return x + y;

};

};

//es6写法

var add = x => (y => x + y);

 

// reduce 实现函数的合并;

var toUpperCase = function(x) { return x.toUpperCase(); };

var exclaim = function(x) { return x + '!'; };

var compose22 = function(...args){

return function(x){

return args.reduceRight(function(pre, cur){

return cur(pre);

},x);

}

}

// 函数第一次执行compose22(exclaim, toUpperCase),记住 自己的args 传入待传入的数组,

// 再次执行的时候,reduce 开始递归执行,初始值为传入的x;

let aaa=compose22(exclaim, toUpperCase)("aaaa");

console.log(aaa);



















 

</script>

</body>

</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值