响应式编程 函数式编程_使用函数式编程技术编写精美JavaScript

响应式编程 函数式编程

函数式编程语言已经在学术界使用了很长一段时间,但是从历史上看,它们没有大量可用的工具和库。 随着.NET平台中Haskell的到来,函数式编程变得越来越流行。 一些传统的编程语言(例如C ++和JavaScript)从函数式编程中导入构造和功能。 在许多情况下,JavaScript中的重复代码会导致笨拙的编码。 如果使用函数式编程,则可以避免所有这些情况。 另外,您可以使用函数式编程样式编写更多的Elegantl回调。

因为函数式编程包含了一种非常不同的程序编写方式,所以习惯命令式范例的程序员会发现学习起来很困难。 在本文中,您将看到有关如何以功能样式在JavaScript中编写优质优雅代码的示例。 我将讨论:

  • 函数式编程概念 ,包括匿名函数,调用函数的不同方式以及如何将函数作为参数传递给其他函数。
  • 使用功能概念 ,并举例说明:扩展数组排序; 用于动态HTML生成的精美代码; 和一系列功能的应用。

函数式程序设计概念

许多开发人员都知道如何用语言进行编码,在这些语言中,您通过描述“如何”来指定解决问题的方法。 例如,要对计算阶乘的函数进行编码,我通过对循环进行编码或使用递归来查找所有数字的乘积来描述程序。 在这两种情况下,程序中都会详细说明计算过程。 清单1显示了阶乘的可能的C代码。

清单1.程序风格的阶乘
int factorial (int n)
{
  if (n <= 0)
    return 1;
  else
    return n * factorial (n-1);
}

这样的语言也称为过程编程语言,因为它们定义了解决问题的过程。 函数式编程与该原理明显不同。 在函数式编程中,您需要描述问题的“原因”。 函数式编程语言也称为声明性语言。 相同的程序计算阶乘将被写为所有数字直到n的乘积。 典型的阶乘函数程序类似于清单2中的示例。

清单2.函数风格的阶乘
factorial n, where n <= 0 	:= 1
factorial n    := foldr * 1 take n [1..]

第二条语句指示您获取从1开始的前n个数字的列表( take n [1..] ),然后查找以1为标识的乘积。 与前面的情况一样,此定义没有循环或递归。 就像阶乘函数的数学定义一样。 一旦知道了库函数( takefoldr )的含义以及表示法( list notation [ ] )的含义,就很容易编写代码,而且可读性强。

从历史上看,由于各种原因,函数式编程语言并不是很流行。 但是,最近,其中一些语言正在进入计算机行业。 一个实例是.NET平台中的Haskell。 在其他情况下,某些现有语言从功能编程语言中借用了概念。 迭代器和延续出现在C ++的某些实现中以及JavaScript中提供的一些功能构造中。 但是,通过借用功能构造,该语言的整体编程范例不会改变。 由于增加了功能构造,JavaScript尚未成为一种功能编程语言。

现在,我将讨论JavaScript中的功能构造的各种优点,以及在日常编码和工作中使用它们的方式。 您将从一些基本功能开始,然后使用它们来查看一些更有趣的应用程序。

匿名功能

在JavaScript中,您可以编写匿名函数或没有名称的函数。 你为什么需要那个? 继续阅读,但是首先您将学习如何编写。 如果您具有以下JavaScript函数:

清单3.一个典型的函数
function sum(x,y,z) {
  return (x+y+z);
}

然后,相应的匿名函数将如下所示:

清单4.一个匿名函数
function(x,y,z) {
  return (x+y+z);
}

要使用它,请编写以下代码:

清单5.应用匿名函数
var sum = function(x,y,z) {
  return (x+y+z);
}(1,2,3);
alert(sum);

使用函数作为值

您也可以将函数用作值。 您可以将具有函数的变量作为为其分配的值。 在最后一个示例中,您还可以执行以下操作:

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

在上面清单6的示例中,变量sum被分配了函数定义本身。 因此,sum是一个函数,可以在任何需要的地方调用。

调用函数的不同方式

JavaScript允许您以两种方式调用函数,如清单78所示

清单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

执行最后一个警报语句将打印值12。

使用功能概念

上一节展示了使用功能样式的一些编程概念。 这些示例绝不是所有概念的完整覆盖,也不以任何重要顺序排列,而是与本讨论相关的概念。 为了快速总结,使用JavaScript中的功能样式:

  • 函数不必始终具有名称。
  • 可以像其他值一样将函数分配给变量。
  • 将编写函数表达式cqn并将其括在括号中,以备后用。
  • 可以将函数作为参数传递给其他函数。

本节显示了一些示例,说明了如何有效使用这些概念在JavaScript中编写精美的代码。 (使用JavaScript的功能样式,您可以执行本讨论范围之外的许多其他事情。)

扩展数组排序
让我们计划编写一个排序方法,该方法可以根据数组元素的日期对其进行排序。 用JavaScript编写此代码非常简单。 数组对象的sort方法采用一个可选参数,即比较函数。 在这种情况下,您需要清单11中的比较功能。
清单11.比较函数
function (x,y) {
	return x.date â???? y.date;
}

要获得所需的功能,请使用清单12中的示例。

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

其中arr是数组类型的对象。 这将根据各自的2012年新ARR的所有对象进行排序。 比较函数及其定义将传递到排序函数以完成排序操作。 具有此功能:

  • 每个JavaScript对象都有一个date属性。
  • JavaScript中数组类型的sort函数带有一个可选参数,该参数是用于排序的比较函数。 这类似于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属性来定义新的函数折叠。 现在,您可以在以后定义的任何数组中使用此函数。

一系列功能的应用
考虑要使用一组函数作为回调函数的情况。 为此,您将使用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中应用函数式编程概念,以一种优雅的方式完成日常活动。 本文中的示例仅显示了少数情况。 如果您为函数式编程确定了正确的方案并应用了这些概念,那么您会很有道理,并且可以提高您的优雅程度。


翻译自: https://www.ibm.com/developerworks/web/library/wa-javascript/index.html

响应式编程 函数式编程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值