Heim  >  Artikel  >  Web-Frontend  >  javascript之典型高阶函数应用介绍二_javascript技巧

javascript之典型高阶函数应用介绍二_javascript技巧

WBOY
WBOYOriginal
2016-05-16 17:44:13932Durchsuche
前言
在前一篇文章javascript之典型高阶函数中主要实现了几个典型的functional函数。文章最后也提出了疑问,为啥那样的实现与F#之类的函数式语言“不太一样”呢?今天来试试更“函数式”的实现。

另一种实现
同样地,尝试对之前实现的函数做一些改动,把for循环去掉。如何去掉呢?这里先要引入一个集合的归纳法定义:

一个集合要么是空集,要么是一个数与一个集合组成的数对从定义可以看到,每一个集合都可以看作为一个数和一个集合的对。例如:{1,2,4,5} 可以认为是数 1 与 集合{2,4,5} 组成的一对,写成(1 , {2,4,5})。递归地,{2,4,5} 可以看成是(2 , {4,5})。最后即为 (5 , Ø)。按照这样的理解,我们就可以用递归的方法消除循环,因为我们在分解的时候已经访问了每一个数据项,并且终结条件为空集。下面就看一下filter函数的另一个实现,原函数名加前缀f以区别之前函数:
复制代码 代码如下:

function ffilter(arr,callback){
var i=arguments[2] || 0,
  out = arguments[3] || [];
if(!arr[i]) return arguments[3];
if(callback(arr[i]))
out.push(arr[i]);
return arguments.callee(arr,callback,++i,out);
}

测试:
复制代码 代码如下:

var arr = [1,2,3,4,5,6,7,8,9,10];
var even = function(item){
if(typeof item !== "number") return false;
return !(item & 1);
};
console.log(ffilter(arr,even));

结果:
[2, 4, 6, 8, 10] 这样消除循环之后,更贴近于数学的归纳定义,显得更自然。同样地,再看一下ffold函数:
复制代码 代码如下:

var arr = [1,2,3,4,5,6,7,8,9,10];
var plus = function(a,b){
return a+b;
};
console.log(ffold(arr,plus,3));

结果:
58
其他函数以同样的方法即可。这样就感觉更functional 了,但能不能再与数学定义更加接近呢?下一次再尝试。
==========2013.1.8 更新==================
上面说到了那些写法能否与数学定义更加接近,下面就尝试一下使用链表。先给出一个定义:
复制代码 代码如下:

var node = function(){
this.data = 0;
this.tail = null;
};

再初始化一个链表
复制代码 代码如下:

var n1 = new node(),n2 = new node(),n3 = new node(),n4 = new node(),n5 = new node();
n1.data=1,n1.tail=n2;
n2.data=2,n2.tail=n3;
n3.data=3,n3.tail=n4;
n4.data=4,n4.tail=n5;
n5.data=5,n5.tail=null;

fold链表版本:
复制代码 代码如下:

function lfold(head,callback,b){
if(!head) return b;
else return callback(head.data,arguments.callee(head.tail,callback,b));
}

输出结果:
18
按照之前的定义,一个集合要么是空集,要么是一个“头”与一个“尾”(集合)组成的数对。每一次调用函数时,分解为head和tail,直到集合为空(写完上面的lfold函数真心感觉太完美了,简直就是定义,要是程序都长这样,注释都不需要了,真是一种享受)。这样子算是最接近数学定义的表示了。因为javascript不支持很多函数式语言的match,所以不能“自动”分解,也就不能直接表示归纳定义。

javascript除了以上的一些东西,还可以实现函数式里面的partial,dojo框架里面的hitch就做到了这一功能,这也是函数式贴近数学的另外一个明显的例子。我将在下一篇博客中讨论。
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn