函数式编程中的一些花样名词

其实我一直不喜欢一些技术术语,原因是它们有时候对于初学者很匪夷所思.不过很多专业术语已经成形,也被大多数人所接受,我们只能委屈求全.下面来看看javascrapt函数式编程的一术花样名词,看看它们长什么样,有什么作用. 1:匿名函数 在函数式编程语言中,函数是可以没有名字的,匿名函数通常表示:“可以完成某件事的一块代码”。这种表达在很多场合是有用的,因为我们有时需要用函数完成某件事,但是这个函数可能只是临时性的,那就没有理由专门为其生成一个顶层的函数对象。比如: 示例1:map 函数 [javascript] function map(array, func) { var res = []; for (var i = 0, len = array.length; i < len; i++) { res.push(func(array[i])); } return res; } var mapped = map([1, 3, 5, 7, 8], function (n) { return n = n + 1; }); console.log(mapped);// 2,4,6,8,9 对数组 [1,3,5,7,8] 中每一个元素加 1 [/javascript] 注意:map 函数的调用,map 的第二个参数为一个函数,这个函数对 map 的第一个参数 ( 数组 ) 中的每一个都有作用,但是对于 map 之外的代码可能没有任何意义,因此,我们无需为其专门定义一个函数,匿名函数已经足够。 2:柯里化 在计算机科学中,Curry化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 [javascript] function adder(num) { return function (x) { return num + x; } } var add3 = adder(3); var add4 = adder(4); console.log(add3(1));//4 console.log(add4(1));//5 [/javascript] 函数 adder 接受一个参数,并返回一个函数,这个返回的函数可以被预期的那样被调用。变量 add3 保持着 adder(3) 返回的函数,这个函数可以接受一个参数,并返回参数与3 的和,不知道和柯里化三个字如何联系起来的.呵呵. 3:高阶函数 高阶函数即为对函数的进一步抽象,事实上,我们在匿名函数小节提到的 map 函数即为一种高阶函数,在很多的函数式编程语言中均有此函数。map(array, func) 的表达式已经表明,将 func 函数作用于 array 中的每一个元素,最终返回一个新的 array,应该注意的是,map 对 array 和 func 的实现是没有任何预先的假设的,完全是根据临时需要进行重写,因此称之为“高阶”函数: [javascript] function map(array, func) { var res = []; for (var i = 0, len = array.length; i < len; i++) { res.push(func(array[i])); } return res; } var mapped = map([1, 3, 5, 7, 8], function (n) { return n = n + 1; }); console.log(mapped);// [2, 4, 6, 8, 9] var mapped2 = map(["one", "two", "three", "four"], function (item) { return "(" + item + ")"; }); console.log(mapped2);// ["(one)", "(two)", "(three)", "(four)"] [/javascript] 月影写的另外一个高阶函数的例子 [javascript] Array.prototype.each = function (closure) { return this.length ? [closure(this[0])].concat(this.slice(1).each(closure)) : []; } [1,2,3,4].each(function(x){return x * 2})得到[2,4,6,8] [1,2,3,4].each(function(x){return x-1})得到[0,1,2,3]。 [/javascript] 4:闭包 这个闭包在javascript里被吵的天翻地覆,有些书中说javascript里的函数就是闭包,还有些说函数的函数(函数嵌套)就是闭包,不过感觉都不怎么精确,按大多数意思理解,闭包是一个执行期概念,如下例子所示:当在一个函数 outter 内部定义另一个函数 inner,而 inner 又引用了 outter 作用域内的变量,在 outter 之外使用 inner 函数,则形成了闭包。它最大的特点是不需要通过传递变量(符号)的方式就可以从内层直接访问外层的环境;描述起来虽然比较复杂,在实际编程中却经常无意的使用了闭包特性。 [javascript] function outter() { var n = 0; return function () { return n++; } } var o1 = outter(); o1(); //n == 0 o1(); //n == 1 o1(); //n == 2 var o2 = outter(); o2(); //n == 0 o2(); //n == 1 [/javascript] 匿名函数 function(){return n++;} 中包含对 outter 的局部变量 n 的引用,因此当 outter 返回时,n 的值被保留 ( 不会被垃圾回收机制回收 ),持续调用 o1(),将会改变 n 的值。而 o2 的值并不会随着 o1() 被调用而改变,第一次调用 o2 会得到 n==0 的结果,用面向对象的术语来说,就是 o1 和 o2 为不同的 实例,互不干涉。 另外闭包的不当使用会造成内存泄露,下次专门写一篇blog说一下.这里暂时说这么多吧.
posted @ 2010-09-05 22:39  7hihi  阅读(178)  评论(0编辑  收藏  举报