技术开发 频道

JavaScript中的函数式编程实践

  使用函数作为值

  也可以将函数作为值使用。还可以拥有一些所赋值是函数的变量。在最后一个示例中,还可以执行以下操作:

清单 6. 使用函数赋值  
var sum
= function(x,y,z)
{    
return (x
+y+z);  
}  
alert(sum(
1,2,3));

 

  在上面清单6的示例中,为变量sum赋的值是函数定义本身。这样,sum就成了一个函数,可以在任何地方调用。

  调用函数的不同方法

  JavaScript允许用两种方式调用函数,如清单7和8所示。

清单 7. 典型的函数应用  
alert (“Hello, World!
");  
或  清单 8. 用函数作为表达式  
(alert)
(“Hello, World!
");

  所以也可以编写以下代码:

清单 9. 定义函数之后就可以立即使用它  
(
function(x,y,z)
{ return (x
+y+z)
} )
(
1, 2, 3);

 

 

  可以在括号中编写函数表达式,然后传递给参数,对参数进行运算。虽然在清单8的示例中,有直接包含在括号中的函数名称,但是按清单9中所示方式使用它时,就不是这样了。

  将函数作为参数传递给其他函数

  也可以将函数作为参数传递给其他函数。虽然这不是什么新概念,但是在后续的示例中大量的使用了这个概念。可以传递函数参数,如清单10所示。

清单 10. 将函数作为参数传递,并应用该函数
var passFunAndApply
= function (fn,x,y,z)
{ return fn(x,y,z); };  
var sum
= function(x,y,z)
{    
return x
+y+z;  };
alert( passFunAndApply(sum,
3,4,5) );
// 12

 

  执行最后一个alert语句输出了一个大小为12的值。

  使用函数式概念

  前一节介绍了一些使用函数式风格的编程概念。所给的示例并没有包含所有的概念,它们在重要性方面也没有先后顺序,只是一些与这个讨论有关的概念而已。下面对JavaScript中的函数式风格作一快速总结:

  ◆函数并不总是需要名称;

  ◆函数可以像其他值一样分配给变量;

  ◆函数表达式可以编写并放在括号中,留待以后应用;

  ◆函数可以作为参数传递给其他函数。

  这一节将介绍一些有效使用这些概念编写优美的JavaScript代码的示例。

  扩展数组排序

  先来编写一个排序方法,可以根据数组元素的日期对数据进行排序。用JavaScript编写这个方法非常简单。数据对象的排序方法接受一个可选参数,这个可选参数就是比较函数。在这里,需要使用清单11中的比较函数。

清单 11. 比较函数  
function (x,y)
{  
return x.date – y.date;
}

 

  要得到需要的函数,请使用清单12的示例。

清单 12. 排序函数的扩展  
arr.sort(
function (x,y) { return x.date – y.date; } );

 

  其中 arr 是类型数组对象。排序函数会根据arr数组中对象的日期对所有对象进行排序。比较函数和它的定义一起被传递给排序函数,以完成排序操作。使用这个函数:

  ◆每个JavaScript对象都有一个date属性。

  ◆JavaScript的数组类型的排序函数接受可选参数,可选参数是用来排序的比较函数。这与C库中的qsort函数类似。

  动态生成HTML的优美代码

  在这个示例中,将看到如何编写优美的代码,从数组动态地生成HTML。可以根据从数据中得到的值生成表格。或者,也可以用数组的内容生成排序和未排序的列表。也可以生成垂直或水平的菜单项目。清单13中的代码风格通常被用来从数组生成动态HTML。

清单 13. 生成动态 HTML 的普通代码  
var str
=' ';  
for (var i=0;i<arr.length;i++)
{    
var element
=arr[i];    
str
+=... HTML generation code...  

 document.write(str);

 

  可以用清单14的代码替换这个代码。

清单 14. 生成动态 HTML 的通用方式  Array.prototype.fold=function(templateFn)
{    
var
len=this.length;    
var str
=' ';    
for (var i=0 ; i<len ; i++)    
str
+=templateFn(this[i]);    
return str;  
}  
function templateInstance(element)
{    
return ... HTML generation code ...  
}  
document.write(arr.fold(templateInstance));

 

  这里使用的是Array类型的prototype属性定义新函数fold。现在可以在后面定义的任何数组中使用该函数。

  系列函数的应用

  考虑以下这种情况:想用一组函数作为回调函数。为实现这一目的,将使用window.setTimeout函数,该函数有两个参数。第一个参数是在第二个参数表示的毫秒数之后被调用的函数。清单15显示了完成此操作的一种方法。

清单 15. 在回调中调用一组函数  
window.setTimeout(
function(){alert(‘First!’);
alert(‘
Second!’);}, 5000);

 

  清单16显示了完成此操作的更好的方式。

清单 16. 调用系列函数的更好的方式  Function.prototype.sequence=function(g)
{    
var f
=this;    
return
function()
{    
f();g();    
}  
};  
function alertFrst() { alert(‘First!’); }  function alertSec() { alert(‘Second!’); }  setTimeout( alertFrst.sequence(alertSec), 5000);

 

  在处理事件时,如果想在调用完一个回调之后再调用一个回调,也可以使用清单16中的代码扩展。这可能是一个需要您自行完成的一个练习,现在您的兴趣被点燃了吧。

  结束语

  在许多领域中都可以应用JavaScript中的函数式编程,以优美的方式完成日常活动。这篇文章中的示例只介绍了几种情况。如果您找到了函数式编程的合适场景,并应用这些概念,那么您就会有更多的理解,并且可以增加您的优美程度。

0
相关文章