Open joeyguo opened 8 years ago
还会有续集么?
@CommanderXL 这里主要是基于一些实践来写的哈,所以以后可能会有续集吧 : p
come from km
@yewang15215 多多指教:D
reduce那里,previous不是上一个值,是上一个调用回调返回的值,我差点以为是上一个数组的值
@qinershi 对哈,已更正
@joeyguo 你好,请教一个问题。
var a = [1, 2, 3];
var b = a.map(x => x);
var c = a.slice();
以上两种创建数组的方式有区别吗?谢谢
@YingshanDeng 结果一致,都可以用来生成新的数组。我想更多的应该是语义上的区别:map表示对当前数组进行处理来映射出一个新值;而slice则是表示从当前数组中取出某块子集来产生一个新值。
@joeyguo thank u👍
@joeyguo 你好,关于不可变的数据实现提供一种方式,不造可行不~
var DATA = ['Functional', 'Programming', {'name': 'demo'}, 'demo1'];
DATA.push(function () {
console.log('DATA func.');
});
/**
* 构造不可变的数据——常量
* @param {Array} originArr 不可变的数组数据
* @param {Number} originValueIndex 要改变的数组元素的index
* @param {anyType} newGetValue 改变成的数组目标元素
* @return {Array} 构造的新的数组数据
* @return {undefined} 构造数据失败
*/
var newArrN = function (originArr, originValueIndex, newGetValue) {
'use strict';
var relArr = null;
if (typeof originValueIndex === 'number') {
relArr = originArr.slice(0);
relArr[ originValueIndex ] = newGetValue;
return relArr;
}
else {
return undefined;
}
};
console.log('原数组的值:');
console.log(DATA);
console.log('Test1:');
console.log(newArrN(DATA, 2, {'name': 'testnumber'}));
console.log('Test2:');
console.log(newArrN(DATA, 1, 'testnumber'));
console.log('原数组的值:');
console.log(DATA);
@wupengju 算是吧,不过上面的实现,用 map 处理可以简洁一些
@joeyguo 最近正在学ES6... 还没到Map = = 后面再用Map来走一波 谢谢回答
貌似跟是跟Anjana Vakil的想法不谋而合,传送门。
@wupengju ES5中就有map了。
原文地址
函数式编程 ( Functional Programming ) 是一种以函数为基础的编程方式和代码组织方式,能够带来更好的代码调试及项目维护的优势。本篇主要结合笔者在实际项目开发中的一些应用,简要谈谈函数式编程。
函数
在函数式编程中,任何代码可以都是函数,且要求具有返回值,如下示例
纯函数
纯函数在这里指函数内外间是“无”关联的。主要有下面两点
不可变数据(immutable)
这里主要是指变量值的不可变。当需要基于原变量值改变时,可通过产生新的变量来确保原变量的不变性,如下
之所以使用这种不变值,除了更好的函数式编程外,还能够维持线程安全可靠,落地在业务中,实际上也能让代码更加清晰。 设想,如果你定义了一个变量A,A在其他地方被其他人修改了,这样是不方便定位A的当前值的。关于定义多个变量引发的内存等问题,可以通过重用结构或部分引用的方式来减轻,可参考 immutable.js
使用 map, reduce 等数据处理函数
强大的 JavaScript 有着越来越多的高能处理数据函数,其中包含了 map、 reduce、 filter 等。
map 能够对原数组中的值进行逐个处理并产生新的数组,一个简单例子
reduce 能够对原数组中的各个值进行结合处理,来产生新的值,如下面例子中,previous 代表上一个结果值,current 代表当前值,reduce 函数可以传入第二个参数作为 previous 初始值,不传时则 previous 初始值为数组中第一个值。
函数柯里化 Currying
柯里化 是将多参函数转换成一系列的单参函数。结合下面例子来说明下
将上面的多参函数进行柯里化,如下
上面柯里化后的函数调用方式也有所转变,第一次传入一个参数返回了一个函数,再传入参数则完成整体的调用,这也是利用的闭包的特性
柯里化后的函数,也可以应用在生产 “ 函数 ” 上,如下示例
组合函数 compose
顾名思义,组合函数是将多个函数进行组合成一个函数。举个例子
上面示例中,当调用组合函数 c 时,传入的参数会经过 b 函数,接着将 b 函数的返回值作为 a 函数的参数值,从而输出最终结果。 组合函数 c 就像管道一样,将水流( 返回值 )流经各个函数中进行处理。
当想要组合很多函数成一条很长很长的“管道”时,那么显然上面的 compose 函数已经不够用了。下面看看 redux 是怎么做这个 compose 工具函数的。
代码很简洁,主要利用了递归方式和数组的 reduceRight 方法来处理,reduceRight 跟上边提到的 reduce 方法功能是一样的,不同的是 reduceRight 是从数组的末尾向前逐个处理。就这样,想拼多长的就多长。
以上,便是笔者在项目实践中应用较多的函数式编程内容,如有不妥,请斧正。
附: 一些可供学习函数式编程的内容
Monads (http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html)
查看更多文章 >> https://github.com/joeyguo/blog