- 浏览: 452437 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
进退取舍:
谢谢,这个用上了!!
Java 一个线程池的示例 -
pb_water:
感谢楼主,打算买楼主的书,支持一下,楼主功德无量
JavaScript内核系列第0版整理稿下载 -
lancezhcj:
有图会直观的多呢,再摸索摸索
有限自动机与建模 -
hsmsyy:
这里应该是原创了吧,楼主我觉得闭包的作用:实现面向对象。有待商 ...
JavaScript内核系列 第7章 闭包 -
wll52:
在应用退出之前,需要释放连接 con.disconnect() ...
使用smack与GTalk通信
大家不要被这个名字诱惑,我讲的是javascript的高阶函数的概念,而不是说本教程为高阶教程。
最近研究SICP,对其中的高阶函数抽象有了一些体会,并用javascript中进行了一些实验,现在把这些实验分析一下,希望对大家有所帮助。
高阶函数思想由来已久,最早可能要追溯到可计算理论的初期,在lambda演算理论中就有了这个思想了。最早的实现可能算是lisp语言。可以说,这个运算模型跟图灵机的计算能力是相当的。只不过后来历史选择了冯诺依曼体系。而lambda只好作为一个虚拟的实现运行在具有同等计算能力的图灵机上。
更高层次的抽象
抽象具有层次,比如,将一个小的运算封装成一个函数,就是一层抽象,而在这个抽象的基础上,再进行一次抽象,即为高阶抽象。在lisp之类的函数编程语言中这个概念是比较基本的。而在其他的命令式编程语言,如C,java等中,提供的是模板或者接口这样的概念。
比如,我们每次需要计算一个数的立方数时,都需要写成x*x*x的形式,如果一个运算中有很多地方要用到立方这种运算的话,可能编码会非常麻烦,而且代码也不清晰,于是,我们可以将立方运算抽象成一个函数,这个函数接受一个输入,并返回这个输入的立方数。
比如:
function cube(x){return x*x*x;}
这样,我们就有了一个独立的模块,用以计算“立方”,并且通过扩展语言的原生语句,我们可以表达“立方”这个概念。这种抽象是容易理解的,像C,java等语言也提供此类的抽象。
下面再看一个例子:
我们先编写一个函数,这个函数的功能如下:
- 输入一个范围[a,b]
- 输出为这个范围中的数的和。
如输入[1,100],输出5050.
这个函数通过递归的形式比较容易实现,如:
function intSum(a, b){ function inc(x){ return x + 1; } function identity(x){ return x; } if(a > b){ return 0; }else{ return intSum( inc(a) , b) + identity(a); } }
当然,其中的内部函数inc,identity实在太简单,完全可以忽略,但是考虑到后边要用到,就先写成这种形式。
这个函数可以很好的工作,但是,随着项目的增大,我们需要另外一个函数来计算某个范围内数的立方和。
- 输入一个范围[a,b]
- 输出为这个范围中的数的立方和
如输入[1,4],输出100:1^3+2^3+3^3+4^3 = 1 + 8 + 27 + 64 = 100
这时候,我们同样可以用一个递归来实现这个函数:
function cubeSum(a, b){ function inc(x){ return x + 1; } function cube(x){ return x * x * x; } if(a > b){ return 0; }else{ return cubeSum( inc(a) , b) + cube(a); } }
随着项目的进一步增长,我们现在需要实现第三个函数,来对这样一个数列进行求和输入同样为[a,b]的一个范围,计算1/x*(x+2),且步长为4,这个数列的前n项的和有个性质,就是无限的接近pi/8这个数列当然是有用的,比如计算Pi值,我们给定一个比较大的范围如[1,10000]然后给这个值乘8,即可近似的计算出pi来。
我用mathematica 计算了一下,可以看出这个求和确实是极限于PI/8.
同样用递归可以实现这个函数:
function piSum(a, b){ function piTerm(x){ return 1/((x+2)*x); } function piNext(x){ return x+4; } if(a > b){ return 0; }else{ return piSum( piNext(a) , b) + piTerm(a); } }
现在,让我们比较一下这三个函数,很快我们就会发现,这三个函数太相似了,都是:
- 比较范围的下标,如果a>b,返回0,否则,转2
- 改变a的值,并对a作一定的运算,然后递归调用自身
可以写成下面的这种伪码形式:
function <funcName>(a, b){ if(a > b){ return 0; }else{ return <funcName>(<next>(a), b) + <func>(a); } }
其中,funcName为函数名,next为取下一个a的值(根据“步长”走一步),func计算a。
我们很容易将这个代码翻译成javascript代码:
function sum(term, a, next, b){ if(a > b){ return 0; }else{ return sum(term, next(a), next, b) + term(a); } }
这时候,如果我们传递给sum这个函数两个额外的参数term,和next,我们就可以得到想要的结果.
现在,我们的求和函数就可以写成这种形式:
function intSum(a, b){ function inc(x){return x + 1;} function identity(x){return x;} return sum(identity, a, inc, b); }
同样,立方和的函数可以写成这样:
function cubeSum(a, b){ function inc(x){return x + 1;} function cube(x){return x * x * x;} return sum(cube, a, inc, b); }
最后一个
function piSum(a, b){ function piTerm(x){ return 1/((x+2)*x); } function piNext(x){ return x+4; } return sum(piTerm, a, piNext, b); }
可以看到,我们只需要传递给sum一个真正的计算算子和一个计算步长的算子就可以了。
现在给出一个简单的测试函数:
function sumTester(){ print(intSum(1, 100)); // should print 5050 print(cubeSum(1, 4)); // should print 100 print(piSum(1, 10000)*8); // should print PI }
两者的运行结果都如下:
5050
100
3.141392653591793
顺便说一下,这些例子均在rhino下测试,在浏览器中没有做过测试,如最后的测试函数中的print,估计浏览器中嵌入的js引擎不能正确解析。关于rhino,javaeye里有相关的文章,可以找找看。
使用高阶函数,我们可以在第一阶抽象的基础上再做一次抽象,生成一个函数的产生器,传递给一定的算子,即可完成各个相似的计算。
评论
curry不属于高阶函数吧?curry是函数式程序设计的一部分,但是高阶函数主要涉及对函数的多级抽象,curry则体现了“函数为一等公民”。
不错,所以这个被作为参数使用的函数被叫做“算子”,即用以执行某项任务的计算单元。函数式编程的重点正在与此!
<code>object.method();</code>
这种情况,需要提供更高级的抽象方式,在函数式编程中,这个“高级”的过程是可以迭代的,所以,你可以通过函数进行任意层次的抽象。
发表评论
-
JavaScript内核系列 第15章 服务器端的JavaScript
2012-02-12 21:39 2326第15章已经在icodeit上发布,这一章分为上/下两篇,请朋 ... -
使用vim开发python及graphviz绘图
2011-12-23 14:49 6458基本需求 使用vim中的autocmd命令可以很容易的将正在 ... -
Java脚本技术应用实例
2011-01-22 11:24 4268前言 一直以来都很喜欢可以自由扩展的软件,这一点应该已经在很 ... -
可编程计算器(phoc)的设计与实现
2011-01-17 11:34 1983前言 借助JavaScript脚本 ... -
函数式编程(javascirpt)
2009-04-18 22:18 1264前言 Javascript,有人称 ... -
C和指针
2009-05-21 23:15 1117前言 指针是C的灵魂,正是指针使得C存在了这么多年,而且将长 ... -
C和指针(续)
2009-05-25 23:41 1360前言 上一篇《C和指针》可能对关于C和指针的有些内容没有说透 ... -
有限自动机与建模
2009-06-06 10:48 1786前言 在学校学程序设计语言的时候,能接触到的所有例子没有一个 ... -
事件和监听器
2009-06-21 22:06 1437前言 事件监听器是经 ... -
基于总线的消息服务(BBMS)的设计与实现
2009-07-25 22:19 1365前言 异步事件的通知机制在比较有规模的软件设计中必然会有涉及 ... -
JavaScript内核系列 第9章 函数式的Javascript
2010-05-13 19:20 3788第九章 函数式的Javascript 要说Ja ... -
JavaScript内核系列 第8章 面向对象的JavaScript(下)
2010-05-06 09:40 3673接上篇:JavaScript内核系列 第8章 面向对象的Jav ... -
JavaScript内核系列 第8章 面向对象的JavaScript(上)
2010-05-06 09:26 2906第八章 面向对象的 Javascript ... -
JavaScript内核系列 第7章 闭包
2010-05-04 08:48 3874第七章 闭包 闭包向来给包括JavaScript程序 ... -
JavaScript内核系列 第6章 正则表达式
2010-04-27 19:44 4050第六章 正则表达式 正则表达式是对字符串的结构 ... -
JavaScript内核系列 第5章 数组
2010-04-24 15:17 4531第五章 数组 JavaScript的数组也是一个比较 ... -
Swing小应用(Todo-List)之三
2010-04-22 20:47 2136前言 去年9月份开发的那个小工具sTodo,只是做到了能用, ... -
JavaScript内核系列 第4章 函数
2010-04-18 17:31 5095第四章 函数 函数,在C语言之类的过程式语言中 ... -
JavaScript内核系列 第3章 对象与JSON
2010-04-12 09:12 6134第三章 对象与JSON JavaScript对象与传 ... -
JavaScript内核系列 第2章 基本概念
2010-04-03 19:44 5690第二章 基本概念 ...
相关推荐
在本文档中,提到的核心知识点是关于JavaScript中的高阶函数。高阶函数是指至少满足下列一个条件的函数:它可以接受一个或多个函数作为参数,也可以返回一个函数。下面将详细解释与高阶函数相关的几个关键概念。 ...
JavaScript中的高阶函数是函数式编程的一个核心特性,它允许函数作为其他函数的参数或返回结果。这种灵活性使得JavaScript能够处理更加复杂的编程任务,尤其是在处理数据操作和异步操作时。接下来,我们将深入探讨高...
Java 模拟 JavaScript 的高阶函数是编程领域中一个有趣且实用的主题,它涉及到语言间的特性差异和跨语言编程的概念。在JavaScript中,高阶函数是指可以接受其他函数作为参数或者返回函数作为结果的函数。这在处理回...
内容概要:本文详细介绍了 JavaScript 中几种重要的高阶函数及其应用方式,其中包括通过 rest 参数传递任意参数(addArrayElements 函数)、数组映射转换(arrToString 方法)、闭包用于封装状态计数器(makeCounter...
在Javascript编程中,高阶函数(Higher-order function)是一类特殊的函数,它们对其他函数进行操作。具体来说,高阶函数可以接受一个或多个函数作为参数,也可以将函数作为其返回值。这类函数概念在很多现代编程...
JavaScript 语言中内置了一些高阶函数,比如 Array.prototype.map、Array.prototype.filter 和 Array.prototype.reduce,它们接受一个函数作为参数,并应用这个函数到列表的每一个元素。 Array.prototype.map() ...
JavaScript 的高阶函数跟 Swift 的高阶函数类似 常见的高阶函数有: Map、Reduce、Filter、Sort 高阶函数是指至少满足下列条件之一的函数 1:函数可以作为参数被传递 2:函数可以作为返回值输出 JavaScript语言...
JavaScript中的Array.prototype方法如`map`、`filter`、`reduce`都是高阶函数的实例,它们用于处理数组而不会改变原数组。 3. **闭包**:闭包是JavaScript中的一个关键特性,它允许函数访问并操作其词法作用域内的...
JavaScript中的高阶函数是编程中的一个核心概念,它在函数式编程中占据着重要的地位。高阶函数的主要特点是能够处理...因此,深入学习JavaScript的高阶函数对于任何希望成为专业JavaScript开发者的人来说都是必要的。
JavaScript支持高阶函数,即可以接受其他函数作为参数或将函数作为返回值的函数。常见的高阶函数包括`forEach`、`map`、`reduce`、`filter`等。这些函数极大地提升了代码的复用性和表达力。 3. 闭包(Closures) ...
在了解JavaScript高阶函数使用之前,首先需要明确什么是高阶函数。在编程中,高阶函数被定义为那些接受函数作为参数或返回函数作为结果的函数。在JavaScript这种弱类型语言中,函数既不对输入的参数类型进行严格定义...
例如,JavaScript中的`Array.prototype.map`就是一个高阶函数,它接受一个函数作为参数,对数组的每个元素应用该函数,然后返回一个新的数组。 在互联网开发中,Lambda和高阶函数的应用非常广泛。比如,前端框架...
JavaScript 高阶函数详解 JavaScript 高阶函数是函数式编程中的一种特殊函数,通过将函数作为参数传入另一个函数,或者将函数作为另一个函数的返回值返回,高阶函数可以抽象我们的代码,将我们的命令式编程转换为...
在JavaScript编程中,高阶函数是非常有用的概念,它们可以作为参数传递给其他函数,或者返回一个新的函数。在这个文档中,重点介绍了在Vue.js应用中如何利用数组的高阶函数来简化代码,特别是`filter()`、`map()`和`...
3. **数组和集合**:学习JavaScript中的数组操作,如map、filter、reduce等高阶函数的运用,以及Set和Map等ES6新增集合类型的使用。 4. **函数**:理解闭包、作用域和this的关键概念,学习箭头函数的语法和特性。 5....
在JavaScript中,函数式编程可以通过利用高阶函数、纯函数、柯里化、函数组合等概念来实现。这种编程风格有助于写出更简洁、可读性强且易于测试的代码。 1. 高阶函数:在JavaScript中,可以将函数作为参数传递给...
JavaScript中的高阶函数是其灵活性和强大的功能之一,它允许函数作为其他函数的参数或返回结果。这样的特性使得代码更加模块化,提高了代码的重用性和可读性。以下是几个高阶函数的应用场景: 1. **回调函数**: ...