函数式编程让JS更优美
来源:冷雨幽森 发布时间:2008-06-10 12:40:00
简介
函数式编程语言在学术领域已经存在相当长一段时间了,但是从历史上看,它们没有丰富的工具和库可供使用。随着 .NET 平台上的 Haskell 的出现,函数式编程变得更加流行。一些传统的编程语言,例如 C++ 和 JavaScript,引入了由函数式编程提供的一些构造和特性。在许多情况下,JavaScript 的重复代码导致了一些拙劣的编码。如果使用函数式编程,就可以避免这些问题。此外,可以利用函数式编程风格编写更加优美的回调。
函数式编程只描述在程序输入上执行的操作,不必使用临时变量保存中间结果。重点是捕捉 “是什么以及为什么”,而不是 “如何做”。与将重点放在执行连续命令上的过程性编程相比,函数式编程的重点是函数的定义而不是状态机(state machine)的实现。
大型知识管理系统应用程序从使用函数式编程风格上受益颇多,因为函数式编程简化了开发。
因为函数式编程采用了完全不同的组织程序的方式,所以那些习惯于采用命令式范例的程序员可能会发现函数式编程有点难学。在这篇文章中,您将了解一些关于如何采用函数式风格,用 JavaScript 编写良好的、优美的代码的示例。我将讨论:
函数式编程概念,包括匿名函数、调用函数的不同方法,以及将函数作为参数传递给其他函数的方式。
函数式概念的运用,采用的示例包括:扩展数组排序;动态 HTML 生成的优美代码;系列函数的应用。
函数式编程概念
在那些通过描述 “如何做” 指定解决问题的方法的语言中,许多开发人员都知道如何进行编码。例如,要编写一个计算阶乘的函数,我可以编写一个循环来描述程序,或者使用递归来查找所有数字的乘积。在这两种情况下,计算的过程都在程序中进行了详细说明。清单 1 显示了一个计算阶乘的可能使用的 C 代码。
过程风格的阶乘
程序代码 程序代码
int factorial (int n)
{
if (n <= 0)
return 1;
else
return n * factorial (n-1);
}
这类语言也叫做过程性 编程语言,因为它们定义了解决问题的过程。函数式编程与这个原理有显著不同。在函数式编程中,需要描述问题 “是什么”。函数式编程语言又叫做声明性 语言。同样的计算阶乘的程序可以写成所有到 n 的数字的乘积。计算阶乘的典型函数式程序看起来如 清单 2 中的示例所示。
函数式风格的阶乘
程序代码
factorial n, where n <= 0 := 1
factorial n := foldr * 1 take n [1..]
第二个语句指明要得到从 1 开始的前 n 个数字的列表(take n [1..]),然后找出它们的乘积,1 为基元。这个定义与前面的示例不同,没有循环或递归。它就像阶乘函数的算术定义。一旦了解了库函数(take 和 foldr)和标记(list notation [ ])的意义,编写代码就很容易,而且可读性也很好。
只用三行 Miranda 代码就可以编写例程,根据参数,使用广度优先或深度优先遍历处理 n 叉树的每个节点,而且元素可以是任何通用类型。
从历史上看,函数式编程语言不太流行有各种原因。但是最近,有些函数式编程语言正在进入计算机行业。其中一个例子就是 .NET 平台上的 Haskell。其他情况下,现有的一些语言借用了函数式编程语言中的一些概念。一些 C++ 实现中的迭代器和 continuation,以及 JavaScript 中提供的一些函数式构造(functional construct),就是这种借用的示例。但是,通过借用函数式构造,总的语言编程范例并没有发生变化。JavaScript 并没因为函数式构造的添加就变成了函数式编程语言。
我现在要讨论 JavaScript 中的函数式构造的各种美妙之处,以及在日常编码和工作中使用它们的方式。我们将从一些基本功能开始,然后用它们查看一些更有趣的应用。
在 JavaScript 中,可以编写匿名函数或没有名称的函数。为什么需要这样的函数?请继续往下读,但首先我们将学习如何编写这样一个函数。如果拥有以下 JavaScript 函数:
典型的函数
程序代码 程序代码
function sum(x,y,z) {
return (x+y+z);
}
然后对应的匿名函数看起来应当如下所示:
匿名函数
程序代码 程序代码
function(x,y,z) {
return (x+y+z);
}
要使用它,则需要编写以下代码:
应用匿名函数
程序代码 程序代码
var sum = function(x,y,z) {
return (x+y+z);
}(1,2,3);
alert(sum);
使用函数作为值
也可以将函数作为值使用。还可以拥有一些所赋值是函数的变量。在最后一个示例中,还可以执行以下操作:
使用函数赋值
程序代码 程序代码
var sum = function(x,y,z) {
return (x+y+z);
}
alert(sum(1,2,3));
在上面示例中,为变量 sum 赋的值是函数定义本身。这样,sum 就成了一个函数,可以在任何地方调用。
调用函数的不同方法,JavaScript 允许用两种方式调用函数。
程序代码 程序代码
alert (“Hello, World!");
或
程序代码 程序代码
(alert) (“Hello, World!");
所以也可以编写以下代码:
定义函数之后就可以立即使用它
程序代码 程序代码
( function(x,y,z) { return (x+y+z) } ) (1, 2, 3);
可以在括号中编写函数表达式,然后传递给参数,对参数进行运算。虽然在 清单 8 的示例中,有直接包含在括号中的函数名称。
也可以将函数作为参数传递给其他函数。虽然这不是什么新概念,但是在后续的示例中大量的使用了这个概念。可以传递函数参数。
将函数作为参数传递,并应用该函数
程序代码 程序代码
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 的值。


猜你喜欢
- 字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value
- 安装先下载源码,地址:ps://pypi.python.org/pypi/IPy/">https://pypi.python
- 在使用Python时,需要使用各种各样的库,通常会使用pip直接安装,这样最为简单也最方便。但最为崩溃的地方在于有时候速度出奇的慢,因为
- 说明Django 默认的用户表 auth_user 包含 id, password, last_login, is_superuser, u
- 直接进入正题解析字符串对象我们都知道,JavaScript对象可以序列化为JSON,JSON也可以解析成对象,但是问题是如果出现了一个既不是
- 一、什么是frame&frame切换?frame:HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素;fram
- 本文实例讲述了Python实现读取邮箱中的邮件功能。分享给大家供大家参考,具体如下:#-*- encoding: utf-8 -*-impo
- 简述和GNU一样,YAML是一个递归着说“不”的名字。不同的是,GNU对UNIX说不,YAML说不的对象是XML。YAML不是XML。为什么
- 一、问题1.1 鼠标放上去不显示文档的提示鼠标放在随意一个函数上面不显示他的说明了我也不知道是咋了二、解决2.1 首先我只记得有一个侧边栏叫
- 介绍Go使用goroutines来处理connection的读写事件,不会阻塞:c, err := srv.newConn(rw) &nbs
- 弹指间,2023已经到来,新的一年,祝大家新年快乐,阖家幸福呀~~~好吧,进入正题,2023的到来,肯定少不了烟花吧(外面不让放炮,那咱们就
- python版本为python3.51.要求1)输入用户名密码2)认证成功后显示欢迎信息3)输错三次后锁定2.需求分析1)用户信息存储在文件
- 通过设置Keras的Tensorflow后端的全局变量达到。import osimport tensorflow as tfimport k
- Windows 8 终于发布了,虽然现在可用的只是开发者预览版,好消息是,IE 10 也随着发了,虽然现在还只有Windows 8可用。我们
- 截图源码Translator.py#!/usr/bin/python# -*- coding: UTF-8 -*-from copy imp
- ps:不曾想还有那么好用的方法。汗一个先。Div即父容器不根据内容自适应高度,我们看下面的代码:<div id="main&
- Anaconda Jupyter安装拓展nbextensions先在终端pip两个包:Pip install jupyter_contrib
- 使用HTMLTestRunner输出的测试报告中,标题和错误说明的中文乱码。环境:python v3.6HTMLTestRunner v0.
- 1、字典(dict)dict = {‘name': ‘Zara', ‘age': 7, ‘class': ‘
- 一个例子: print("Loading vgg19 weights...")vgg_mode