什么是函數式編程?如果你這么直白地詢問,會發現它竟是一個不太容易解釋的概念。許多在程序設計領域有著多年經驗的老手,也 " /> 国产在线视频一区,国内精品视频一区二区三区,精品欧美视频

中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

JavaScript與函數式編程解釋

作者:月影
牢記:函數式編程不是用函數來編程!!!
23.4函數式編程 
23.4.1 什么是函數式編程

        什么是函數式編程?如果你這么直白地詢問,會發現它竟是一個不太容易解釋的概念。許多在程序設計領域有著多年經驗的老手,也無法很明白地說清楚函數式編程到底在研究些什么。函數式編程對于熟悉過程式程序設計的程序員來說的確是一個陌生的領域,閉包(closure),延續(continuation),和柯里化(currying)這些概念看起來是這么的陌生,同我們熟悉的if、else、while沒有任何的相似之處。盡管函數式編程有著過程式無法比擬的優美的數學原型,但它又是那么的高深莫測,似乎只有拿著博士學位的人才玩得轉它。

        提示:這一節有點難,但它并不是掌握JavaScript所必需的技能,如果你不想用JavaScript來完成那些用Lisp來完成活兒,或者不想學函數式編程這種深奧的技巧,你完全可以跳過它們,進入下一章的旅程。

        那么回到這個問題,什么是函數式編程?答案很長……

函數式編程第一定律:函數是第一型。

        這句話本身該如何理解?什么才是真正的第一型?我們看下面的數學概念:

        二元方程式 F(x, y) = 0,x, y 是變量, 把它寫成 y = f(x), x是參數,y是返回值,f是由x到y的映射關系,被稱為函數。如果又有,G(x, y, z) = 0,或者記為 z = g(x, y),g是x、y到z的映射關系,也是函數。如果g的參數x, y又滿足前面的關系y = f(x), 那么得到z = g(x, y) = g(x, f(x)),這里有兩重含義,一是f(x)是x上的函數,又是函數g的參數,二是g是一個比f更高階的函數。
        這樣我們就用z = g(x, f(x)) 來表示方程F(x, y) = 0和G(x, y, z) = 0的關聯解,它是一個迭代的函數。我們也可以用另一種形式來表示g,記z = g(x, y, f),這樣我們將函數g一般化為一個高階函數。同前面相比,后面這種表示方式的好處是,它是一種更加泛化的模型,例如T(x,y) = 0和G(x,y,z) = 0的關聯解,我們也可以用同樣的形式來表示(只要令f=t)。在這種支持把問題的解轉換成高階函數迭代的語言體系中,函數就被稱為“第一型”。
        JavaScript中的函數顯然是“第一型”。下面就是一個典型的例子:

        Array.prototype.each = function(closure)
                {
                return this.length ? [closure(this[0])].concat(this.slice(1).each(closure)) : [];
                }

這真是個神奇的魔法代碼,它充分發揮了函數式的魅力,在整個代碼中只有函數(function)和符號(Symbol)。它形式簡潔并且威力無窮。
[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]。

函數式和面向對象的本質都是“道法自然”。如果說,面向對象是一種真實世界的模擬的話,那么函數式就是數學世界的模擬,從某種意義上說,它的抽象程度比面向對象更高,因為數學系統本來就具有自然界所無法比擬的抽象性。

函數式編程第二定律:閉包是函數式編程的摯友。

閉包,在前面的章節中我們已經解釋過了,它對于函數式編程非常重要。它最大的特點是不需要通過傳遞變量(符號)的方式就可以從內層直接訪問外層的環境,這為多重嵌套下的函數式程序帶來了極大的便利性,下面是一個例子:

(function outerFun(x)
{
        return function innerFun(y)
        {
                return x * y;
        }
})(2)(3);

函數式編程第三定律:函數可以被科里化(Currying)。

什么是Currying? 它是一個有趣的概念。還是從數學開始:我們說,考慮一個三維空間方程 F(x, y, z) = 0,如果我們限定z = 0,于是得到 F(x, y, 0) = 0 記為 F'(x, y)。這里F'顯然是一個新的方程式,它代表三維空間曲線F(x, y, z)在z = 0平面上的兩維投影。記y = f(x, z), 令z = 0, 得到 y = f(x, 0),記為 y = f'(x), 我們說函數f'是f的一個Currying解。
下面給出了JavaScript的Currying的例子:
function add(x, y)
{
        if(x!=null && y!=null) return x + y;
                else if(x!=null && y==null) return function(y)
                {
                return x + y;
                }
                else if(x==null && y!=null) return function(x)
                {
                       return x + y;
                 }
}
var a = add(3, 4);
var b = add(2);
var c = b(10);

上面的例子中,b=add(2)得到的是一個add()的Currying函數,它是當x = 2時,關于參數y的函數,注意到上面也用到了閉包的特性。

有趣的是,我們可以給任意函數一般化Currying,例如:

function Foo(x, y, z, w)
{
        var args = arguments;

        if(Foo.length < args.length)
                return function()
                {
                        return 
args.callee.apply(Array.apply([], args).concat(Array.apply([], arguments)));
                }
        else
                return x + y  主站蜘蛛池模板: 久久久久国产一区二区三区四区 | 中文字幕亚洲一区 | 国产免费一区二区三区 | 亚洲+变态+欧美+另类+精品 | 8x国产精品视频一区二区 | 婷婷91| 久久亚洲国产精品日日av夜夜 | 九九在线视频 | 天天射网站 | 99精品热视频| 中文字幕亚洲区一区二 | 欧洲视频一区二区 | 久热爱 | 狠狠做六月爱婷婷综合aⅴ 国产精品视频网 | 一本一道久久a久久精品综合蜜臀 | 国产免费看 | 激情 一区| 一区二区三区免费 | 国久久 | www.yw193.com | www成年人视频 | 成人午夜毛片 | 中文字幕影院 | 日韩激情在线 | 日本一区二区高清不卡 | 亚洲第一av| 国产一区二区电影网 | 日本不卡一二三 | 天天射天天操天天干 | 日韩福利在线 | 婷婷综合 | 成人久久18免费网站麻豆 | 精品91视频| 日韩1区 | 美女在线一区二区 | 欧美精品一区二区三区四区 在线 | 美女一级a毛片免费观看97 | 91五月婷蜜桃综合 | 一区二区三区免费 | 亚洲网站免费看 | 奇米超碰在线 |