函数式JavaScript编程指南
- 格式:pdf
- 大小:171.58 KB
- 文档页数:9
简介你是否知道JavaScript其实也是一个函数式编程语言呢?本指南将教你如何利用JavaScript的函数式特性。
要求:你应当已经对JavaScript和DOM有了一个基本的了解。
写这篇指南的目的是因为关于JavaScript编程的资料太多了但是极少的资料提到了JavaScript 的函数式特性。
在本指南中,我只会讲解这些基本知识而不会深入其它的函数式语言或这是Lambda算子。
你可以点击所有的例子然后你所看到的代码就会被执行,这样就可以令指南变得具有交互性。
你也可以使用这个沙箱来尝试。
第一课——匿名函数我们将首先介绍[i]匿名函数[/i]。
一个匿名函数就是一个没有名字的函数。
你可以认为他们是一次性函数。
当你只需要用一次某个函数式,他们就特别有用。
通过使用匿名函数,没有必要把函数一直放在内存中,所以使用匿名函数更加有效率。
例Example:下面两个函数处理同样的事情,而average在给z赋值结束之后一直保留——但匿名函数则不会。
function average(x,y) { return (x+y)/2;}var z = average(1,3);alert(z);var z = function(x,y) { return (x+y)/2; } (1,3);alert(z);这很自然得引出了我们下面的一节课函数作为值。
第二课 - 函数作为值事实上,我们一般在JavaScript中声明函数的方式可以看作是一个简化了的语法(也就是[i]语法糖[/i],[i]syntactic sugar[/i])。
例:下面两个表达式其实完全一样。
所以左边的表达式仅仅是右边的简写function average(x,y){ return (x+y)/2;}alert( average(1,3) );var average = function(x,y){ return (x+y)/2;}alert( average(1,3) );从这里可以得出一个结论,函数是一个值就像字符串、数字或数组一样。
这还出现几个问题:我是否可以把函数作为参数传递?可以,见下面的例子。
是否可以实时生成函数?当然了,这是一个高级的主题,它可以通过eval 函数来完成。
[b]小提示:看看本页面的源代码。
例:这个例子演示了如何把函数作为参数传递。
var applyFun = function (f,x,y) { return f(x,y); };var add = function(x,y) { return x+y;};alert( applyFun(add,3,4) ); // 7第三课 - 两种方式调用函数在JavaScript中,有两种调用函数的方式。
一般的方式是把参数放在括号中,如alert(42)。
另一种方式是同时把函数和参数都放在括号中,如(alert)(42)。
例:alert(42);(alert) (42);(function(x) { alert(x-13); }) (55);为什么函数两边的括号很重要:如果你写了括号,那么在括号中的代码就会被先计算。
在计算之后,括号所在的地方就会有一个值。
这个值可能是一个字符串、一个数字或一个函数。
第四课- “短路”条件调用现在我们将学习如何使用“短路”条件调用。
使用这个方法可以缩短源代码同时代码也变得更加可读。
例:这个语法并不是用在左表达式上,而是用在右表达式上。
var f = false; var t = true;var z;if(f)z = 4;else if(t)z = 2;alert(z);var f = false; var t = true;var z = (f && 4) || (t && 2);alert(z);第五课 - 它好在哪里OK,现在我们已经学习了一些函数式JavaScript的内容。
那么它好在哪里?函数式JavaScript 编程之所以很重要有三条主要的理由:•它有助于写出模块化和可服用的代码。
•它对事件处理程序非常有效。
•它很有趣!在下面的篇幅中,我会给出更多关于前两条理由的信息1. 模块化和可复用的代码现在你已经知道如何将函数作为值使用,那么你也应该试试!一个很好的例子是数组内建的sort方法。
预定义的sort()把所有的对象转换成字符串并把他们按照词语的顺序排序。
但如果我们有用户自定义的对象或者数字那么它就不是很有用了。
于是这个函数可以让你给他一个进行比较的函数作为参数,如sort(compareFunction)。
这个方法让我们甚至不用接触实际的sort方法。
例:var myarray = new Array(6,7,9,1,-1);var sortAsc = function(x,y) { return x-y; };var sortDesc = function(x,y) { return y-x; };myarray.sort(sortDesc);alert(myarray);myarray.sort(sortAsc);alert(myarray);2. 事件处理程序对事件处理程序使用函数式编程也许是最直观的函数作为值得应用了。
既然这样我们马上就演示一个例子。
简单的例子:;ie现在有一个Button类,带一个自定义的onclick行为。
function Button(clickFunction) { this.button = document.createElement("button"); this.button.appendChild(document.createTextNode("Press me!")); this.button.onclick = clickFunction;}var bt = new Button(function() { alert("42"); });练习:为什么我们要把alert包裹在一个匿名函数中?高级例子:现在我们想改进我们的Button类。
每一个按钮都被分配了一个值当按钮被点击时显示该值。
首先我们调整我们的类:function Button(value) { this.value = value; this.button = document.createElement("button"); this.button.appendChild(document.createTextNode("test"));}下面你也许要尝试写下面的代码:this.button.onclick = function() { alert(this.value); };如果你执行它你就会发现提示框中间是空的。
为什么会这样呢?其实原因在于JavaScript的可见性规则。
当onclick函数被执行时this指向的是按钮的DOM节点而非自定义的按钮对象。
我们如何解决这个问题?使用函数式编程:this.button.onclick = (function(v) { return function() { alert(v); };}) (this.value);这种情况下执行该匿名函数会将v绑定到this.value上。
函数式编程概念,包括匿名函数、调用函数的不同方法,以及将函数作为参数传递给其他函数的方式。
函数式概念的运用,采用的示例包括:扩展数组排序;动态 HTML 生成的优美代码;系列函数的应用。
函数式编程概念在那些通过描述 “如何做” 指定解决问题的方法的语言中,许多开发人员都知道如何进行编码。
例如,要编写一个计算阶乘的函数,我可以编写一个循环来描述程序,或者使用递归来查找所有数字的乘积。
在这两种情况下,计算的过程都在程序中进行了详细说明。
清单 1 显示了一个计算阶乘的可能使用的 C 代码。
清单 1. 过程风格的阶乘int factorial (int n){if (n <= 0)return 1;elsereturn n * factorial (n-1);}这类语言也叫做过程性 编程语言,因为它们定义了解决问题的过程。
函数式编程与这个原理有显著不同。
在函数式编程中,需要描述问题 “是什么”。
函数式编程语言又叫做声明性 语言。
同样的计算阶乘的程序可以写成所有到 n 的数字的乘积。
计算阶乘的典型函数式程序看起来如 清单 2 中的示例所示。
清单 2. 函数式风格的阶乘factorial n, where n <= 0 := 1factorial 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 函数:清单 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);使用函数作为值也可以将函数作为值使用。