成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 函數(shù)式編程 -- 劃重點(diǎn)了?。?!

weizx / 3293人閱讀

摘要:函數(shù)是一等公民在談到函數(shù)式編程的時(shí)候,很多時(shí)候會(huì)聽(tīng)到這樣一句話函數(shù)是一等公民。變量作用域和閉包變量作用域變量的作用域和閉包作為的基礎(chǔ),在學(xué)習(xí)函數(shù)式編程中是非常重要的,只有理解了它們,你才能更好的去理解我們后面要講到的高階函數(shù)和部分應(yīng)用等。

函數(shù)是一等公民

在談到函數(shù)式編程的時(shí)候,很多時(shí)候會(huì)聽(tīng)到這樣一句話 "函數(shù)是一等公民"。那我們?nèi)绾稳ダ斫膺@句話呢?

"一等" 這個(gè)術(shù)語(yǔ)通常用來(lái)描述值。所以當(dāng)我們說(shuō) "函數(shù)是一等公民" 時(shí),也就是說(shuō)函數(shù)擁有值的一切特性,你可以像看待一個(gè)值一樣來(lái)看待一個(gè)函數(shù)。舉個(gè)例子,數(shù)字在 JavaScript 中是一等公民,那么數(shù)字擁有的特性,也同樣被函數(shù)所擁有。

函數(shù)可以像數(shù)字一樣被存儲(chǔ)為一個(gè)變量

const num = 10;
const fun = function() {
    return 10;
}

函數(shù)可以像數(shù)字一樣作為數(shù)組的一個(gè)元素

const a = [10, function() { return 20; } ]

函數(shù)可以像數(shù)字一樣存在于對(duì)象的插槽里

const b = {
    name: "Tony",
    age: function() { 
        return 20; 
    }
}

函數(shù)可以像數(shù)字一樣在使用時(shí)直接創(chuàng)建出來(lái)

10 + (function() { return 20; })(); // 30

函數(shù)可以像數(shù)字一樣被另一個(gè)函數(shù)返回

const well = function() {
    return 10;
}

const good = function() {
    return function() {
        return 10;
    };
}

函數(shù)可以像數(shù)字一樣被傳遞給另一個(gè)函數(shù)

const fun = function(value) { 
    return value; 
}

const happy = function(func) {
    return func(5) * 10;
}

happy(fun); // 50

最后兩條其實(shí)就是 高階函數(shù) 的定義,如果你現(xiàn)在不理解也沒(méi)有關(guān)系,我們?cè)诤竺娴牟糠謺?huì)講到它。

變量作用域和閉包 變量作用域

變量的作用域和閉包作為 JavaScript 的基礎(chǔ),在學(xué)習(xí)函數(shù)式編程中是非常重要的,只有理解了它們,你才能更好的去理解我們后面要講到的高階函數(shù)和部分應(yīng)用等。

關(guān)于變量的作用域,你需要知道:

全局作用域: JavaScript 中擁有最長(zhǎng)生命周期 (一個(gè)變量的多長(zhǎng)的時(shí)間內(nèi)保持一定的值) 的變量,其變量的生命周期將跨越整個(gè)程序。

globalVariable = "This is a global variable!";

詞法作用域: 詞法作用域其實(shí)就是指一個(gè)變量的可見(jiàn)性,以及它文本表述的模擬值。

a = "outter a";

function good() {
    a = "middle a";
    return function() {
        a = "inner a";
        return "I am " + a;
    }
}

good(); // I am inner a
PS:這里的示例代碼僅僅是為了學(xué)習(xí),你最好不要這樣去寫,因?yàn)樗鼤?huì)讓你的代碼變得令人費(fèi)解。

在上面的例子中,我們分別對(duì) a 變量進(jìn)行了三次賦值,那么為什么最后我們拿到 a 的值是 "inner a" 而非其他呢?

當(dāng)我們聲明 a = "outter a" 時(shí),程序會(huì)在棧中開(kāi)辟一個(gè)空間去存儲(chǔ) a,當(dāng)執(zhí)行 good()函數(shù)時(shí),我們聲明了 a = "middle a",這時(shí)候會(huì)將棧中 a 的值修改掉,變成 "middle a",最后在執(zhí)行 return 語(yǔ)句時(shí),我們又聲明了 a = "inner a",這時(shí)候會(huì)再次修改棧中的 a 的值,變成 "inner a"。因此得到了上面的結(jié)果。

在多次給同一變量賦值時(shí),最后得到的值是離使用時(shí)最近的一次賦值。通過(guò)查找離使用時(shí)最近的一次賦值,我們可以快速的得出最后的結(jié)果。

動(dòng)態(tài)作用域

提到 JavaScript 的動(dòng)態(tài)作用域,就不得不提到 this 了。this 相關(guān)的知識(shí)很多,之后有時(shí)間再詳細(xì)來(lái)講講?,F(xiàn)在我們先記住 this 所指向的值由調(diào)用者確定,如下代碼所示:

function globalThis() { return this; }

globalThis.call("APPLE"); //=> "APPLE"
globalThis.call("ORANGE"); //=> "ORANGE"

函數(shù)作用域

閉包

說(shuō)起閉包,很多人都會(huì)覺(jué)得有點(diǎn)頭疼,這的確是一個(gè)令人費(fèi)解的概念,不過(guò)不要怕,它其實(shí)沒(méi)有那么難以理解。

閉包的定義

閉包是一個(gè)函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合

換句話說(shuō),閉包就是在使用時(shí)被作用域封閉的變量和函數(shù)。閉包可以捕獲函數(shù)的參數(shù)和變量。

舉個(gè)例子:

const fun = function() {
    const a = 10;
    return function(b) {
         return a + b;
    }
}
const myFunc = fun(); // 此時(shí) myFunc 就變成一個(gè)閉包了,這個(gè)閉包可以捕獲 fun 函數(shù)里的 a 變量,b 參數(shù)。

注意閉包是在使用時(shí)才會(huì)生成的,而非創(chuàng)建時(shí)。如上面的例子,如果只創(chuàng)建 fun 函數(shù),而不執(zhí)行最后一句 fun(),那么 fun 并不能稱之為一個(gè)閉包。這里的閉包應(yīng)該是 fun 運(yùn)行時(shí)所產(chǎn)生的作用域,這個(gè)作用域捕獲了fun 里面的變量和參數(shù)。

閉包的特點(diǎn)

閉包會(huì)捕獲一個(gè)值(或引用),并多次返回相同的值

每一個(gè)新的閉包都會(huì)捕獲不一樣的值

再來(lái)看一個(gè)例子:

const fun = function() {
    return function() {
        return 10;
    }
}

const myFunc = fun(); // myFunc 不是一個(gè)閉包

const fun2 = function(value) {
    return function() {
        return value;
    }
}
const myFunc2 = fun2("AWESOME"); // myFunc2 是一個(gè)閉包
myFunc2(); // AWESOME
myFunc2(); // AWESOME 多次執(zhí)行 myFunc2 閉包,返回的值相同

const myFunc3 = fun2("HAPPY"); // myFunc3 是一個(gè)新的閉包
myFunc3(); // HAPPY

這里 myFunc 嚴(yán)格意義上并不能叫作一個(gè)閉包,因?yàn)樗](méi)有捕獲 fun 任何的變量或者是函數(shù)的傳參。而 myFunc2 是一個(gè)閉包,因?yàn)樗东@了 fun2 的傳參。

閉包的銷毀

閉包延續(xù)了變量的生命周期,如果不手動(dòng)銷毀,閉包里面的變量會(huì)一直存在內(nèi)存中。比如當(dāng)我們手動(dòng)將 myFunc = null 時(shí),閉包里面的變量才會(huì)被垃圾回收。

實(shí)用的閉包

說(shuō)了這么多,你可能會(huì)有這樣的疑問(wèn),閉包真的有用嗎?閉包一般都會(huì)用到什么地方?

*1. 用閉包模擬私有方法, 使公共函數(shù)能夠訪問(wèn)私有函數(shù)和變量,實(shí)現(xiàn)數(shù)據(jù)的隱藏和封裝。私有方法有利于限制對(duì)代碼的訪問(wèn),并且提供了強(qiáng)大的管理命名空間的能力,避免了非核心代碼對(duì)公共接口的干擾。

const Counter = () => {
    let count = 0;
    
    const change = (a) => {
        count = count + a;
    }
    
    return {
        increase: () => {
            change(1);
        },
        decrease: () => {
            change(- 1);
        },
        value: () => {
            return count;
        }
    }
}

const func1 = new Counter();
func1.value();  // 0

func1.increase(); 
func1.value(); // 1

func1.decrease();
func1.value(); // 0

*2. 通過(guò)一個(gè)高階函數(shù),生成不同的閉包,從而得到多個(gè)保存不同環(huán)境的新函數(shù)。

如下面的例子:

const makeAdder = function(x) {
    return function(y) {
        return x + y;
    }
}

const add5 = makeAdder(5);
const add10 = makeAdder(10);

makeAdder 其實(shí)是一個(gè)函數(shù)工廠,用于創(chuàng)建將制定的值和它的參數(shù)求和的函數(shù)。通過(guò)它我們又創(chuàng)建了兩個(gè)新函數(shù) add5 和 add10。add5 和 add10 都是閉包。它們共享著相同的函數(shù)定義,但是卻保存了不同的環(huán)境。在 add5 的環(huán)境中,x 為 5,但是在 add10 中,x 則為10。

高階函數(shù) 定義

滿足以下任意條件之一即可稱之為高階函數(shù):

以一個(gè)或者多個(gè)函數(shù)作為參數(shù)

以一個(gè)函數(shù)作為返回結(jié)果

我們常見(jiàn)的 map,find,reduce 都是以函數(shù)作為入?yún)⒌暮瘮?shù),所以它們都是高階函數(shù)。

以函數(shù)作為參數(shù)的函數(shù)

使用函數(shù)作為函數(shù)的參數(shù),可以讓我們創(chuàng)建出更靈活的函數(shù)。通過(guò)將參數(shù)從值替換為函數(shù),我們可以得到更多的可能性。因?yàn)樵谡{(diào)用的時(shí)候,我們可以通過(guò)傳入不同的函數(shù)來(lái)完成不同的需求。

正如下面的例子:

const finder = function(val, func) {
    return val.reduce(function(prev, current) {
        return func(prev, current);
    });
}

const a = [1, 2, 3, 5, 8];
finder(a, Math.max); // 8
finder(a, Math.min); // 1

在使用 finder 函數(shù)時(shí),通過(guò)傳入不同的函數(shù),最后得到了完全不同的結(jié)果。這也是為什么我們強(qiáng)調(diào) "使用函數(shù),而不是值" 的原因。

以函數(shù)作為返回結(jié)果的函數(shù)

以函數(shù)作為返回結(jié)果的函數(shù),可以構(gòu)建強(qiáng)大的函數(shù)。還記得我們前面提到的閉包嗎? 通過(guò)高階函數(shù) makeAdder,我們生成了 add5 和 add10 兩個(gè)新的函數(shù)。能夠生成閉包的函數(shù),其實(shí)都是高階函數(shù)。

到這里,第一部分重點(diǎn)內(nèi)容就講完了。在下一部分中,我們會(huì)講到函數(shù)式編程中剩下的幾個(gè)重要部分:

柯里化和組合

部分應(yīng)用

遞歸

基于流的編程

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90738.html

相關(guān)文章

  • 【響應(yīng)編程的思維藝術(shù)】 (3)flatMap背后的代數(shù)理論Monad

    摘要:本文是響應(yīng)式編程第二章序列的深入研究這篇文章的學(xué)習(xí)筆記。函數(shù)科里化的基本應(yīng)用,也是函數(shù)式編程中運(yùn)算管道構(gòu)建的基本方法。四資料參考函數(shù)式編程指南 本文是Rxjs 響應(yīng)式編程-第二章:序列的深入研究這篇文章的學(xué)習(xí)筆記。示例代碼托管在:http://www.github.com/dashnowords/blogs 更多博文:《大史住在大前端》目錄 showImg(https://segme...

    MorePainMoreGain 評(píng)論0 收藏0
  • 前端小知識(shí)--TypeSript和JavaScript到底是什么關(guān)系?

    摘要:想學(xué)好前端,真的要主動(dòng),然后對(duì)所有的英文文檔耐心一點(diǎn)。在年月日,國(guó)際組織發(fā)布了的第六版,該版本正式名稱為,但通常被稱為或者。自此,每年發(fā)布一次新標(biāo)準(zhǔn)。但保留了用于依賴注入的構(gòu)造函數(shù)參數(shù)類型。必須在構(gòu)造函數(shù)中聲明屬性,而不是在類的代碼體中。 從 TypeScript 到 ES6 到 ES5 在我初學(xué)前端的很長(zhǎng)一段時(shí)間,不愿意碰git,不愿意碰框架,總是嫌麻煩,連ES6也沒(méi)有怎么去弄明白...

    sixleaves 評(píng)論0 收藏0
  • 【響應(yīng)編程的思維藝術(shù)】 (2)響應(yīng)Vs面向?qū)ο?/b>

    摘要:本文是響應(yīng)式編程第一章響應(yīng)式這篇文章的學(xué)習(xí)筆記。通過(guò)代碼對(duì)比可以發(fā)現(xiàn),在響應(yīng)式編程中,我們不再用對(duì)象的概念來(lái)對(duì)現(xiàn)實(shí)世界進(jìn)行建模,而是使用流的思想對(duì)信息進(jìn)行拆分和聚合。 本文是Rxjs 響應(yīng)式編程-第一章:響應(yīng)式這篇文章的學(xué)習(xí)筆記。示例代碼地址:【示例代碼】 更多文章:【《大史住在大前端》博文集目錄】 showImg(https://segmentfault.com/img/bVbuE...

    Tonny 評(píng)論0 收藏0
  • 【響應(yīng)編程的思維藝術(shù)】 (5)Angular中Rxjs的應(yīng)用示例

    摘要:本文是響應(yīng)式編程第四章構(gòu)建完整的應(yīng)用程序這篇文章的學(xué)習(xí)筆記。涉及的運(yùn)算符每隔指定時(shí)間將流中的數(shù)據(jù)以數(shù)組形式推送出去。中提供了一種叫做異步管道的模板語(yǔ)法,可以直接在的微語(yǔ)法中使用可觀測(cè)對(duì)象示例五一點(diǎn)建議一定要好好讀官方文檔。 本文是【Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的Web應(yīng)用程序】這篇文章的學(xué)習(xí)筆記。示例代碼托管在:http://www.github.com/dashnoword...

    shenhualong 評(píng)論0 收藏0
  • JavaScript系列(四) - 收藏集 - 掘金

    摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠?lái)都是中的主導(dǎo)范式。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠?lái)都是JavaScript中的主導(dǎo)范式。JavaScript作為一門多范式編程語(yǔ)言,然而,近幾年,函數(shù)式編程越來(lái)越多得受到開(kāi)發(fā)者的青睞。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。因此,...

    cfanr 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<