国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端進(jìn)擊的巨人(四):略知函數(shù)式編程

omgdog / 2349人閱讀

摘要:自執(zhí)行函數(shù)閉包實現(xiàn)模塊化以樂之名程序員產(chǎn)品經(jīng)理對作用域,以及閉包知識還沒掌握的小伙伴,可回閱前端進(jìn)擊的巨人三從作用域走進(jìn)閉包。參考文檔利用閉包實現(xiàn)模塊化翻譯淺談中的高階函數(shù)系列更文請關(guān)注專欄前端進(jìn)擊的巨人,不斷更新中。。。

系列更文前三篇文章,圍繞了一個重要的知識點(diǎn):"函數(shù)"
函數(shù)調(diào)用棧、函數(shù)執(zhí)行上下文、函數(shù)作用域到閉包。可見不理解函數(shù)式編程,代碼都擼不好。

?函數(shù)是一等公民

函數(shù)與其它數(shù)據(jù)類型一樣,可以作為值賦給變量,作為參數(shù)傳遞或返回值返回,也可以像對象一樣給函數(shù)創(chuàng)建屬性(不推薦給函數(shù)加屬性,雖然可用)。

函數(shù)在實際開發(fā)中應(yīng)用:

函數(shù)聲明

函數(shù)表達(dá)式

匿名函數(shù)

自執(zhí)行函數(shù)

// 函數(shù)聲明
function getName() {
    //...    
}

// 函數(shù)表達(dá)式
var getName = function() {
    //...
}

// 匿名函數(shù)
setTimeout(function(){
    //...
}, 1000);

// 自執(zhí)行函數(shù)
(function(){
    //...
})();
何為一等:優(yōu)先級

函數(shù)聲明在"執(zhí)行上下文創(chuàng)建階段"就會進(jìn)行聲明并賦值,而var聲明變量會初始化為undefined,實際賦值會等到"執(zhí)行上下文執(zhí)行階段"。函數(shù)表達(dá)式使用var來聲明,因此它遵循的是變量聲明的規(guī)則。( 如果函數(shù)名與變量重名,函數(shù)優(yōu)先賦值)

"函數(shù)聲明優(yōu)先級高于變量聲明和函數(shù)表達(dá)式,自稱一等公民。"

// 代碼書寫:
console.log(getName);
getName();
var getName;
getName = "我的名字";
function getName(){
    //...
}
console.log(getName);

// 實際執(zhí)行
var getName;            // 變量名與函數(shù)名重名,函數(shù)優(yōu)先賦值
function getName() {
    //...
}
console.log(getName);
getName();
getName = "我的名字";
console.log(getName);
函數(shù)式編程

函數(shù)式編程是一種編程思維方式,它建議我們在程序編寫時,對復(fù)用性高的功能代碼進(jìn)行函數(shù)封裝,實現(xiàn)代碼的高復(fù)用性。

新手朋友往往是一塊代碼多次出現(xiàn)在不同的地方,常見的例子就是ajax請求方法運(yùn)用,在需要請求后端數(shù)據(jù)時多次出現(xiàn)一串ajax請求代碼。

如果想要對ajax請求統(tǒng)一做異常處理,或管理后端返回狀態(tài)碼,是不是每處代碼都要修改???但是如果把ajax請求代碼封裝成一個函數(shù),接口url和數(shù)據(jù)data通過參數(shù)傳遞到函數(shù)內(nèi)部處理,后期擴(kuò)展維護(hù)都方便修改,復(fù)用性擴(kuò)展性都更加優(yōu)秀。

所以實際敲代碼過程中,要經(jīng)常提醒自己運(yùn)用函數(shù)式編程的思維方式,只要有可能出現(xiàn)多次的業(yè)務(wù)邏輯代碼,那么就要考慮是否封裝成函數(shù),以便后續(xù)統(tǒng)一調(diào)用。

function sumScore(list) {
    var totalScore = 0
    for (var i = 0; i < list.length; i++) {
        totalScore += list[i];        
    }
    return totalScore;    
}

var list = [10, 8, 9, 7];
var totalScore = sumScore(list);    // 計算總分

TIPS: 函數(shù)名建議使用動詞,如addUser(),sumScore(),getUser()...

純函數(shù)
純函數(shù):相同的輸入對應(yīng)相同的輸出,穩(wěn)定沒有副作用(不改變外部變量的值)
相同的輸入,相同的輸出

相同的參數(shù)傳入調(diào)用,要有相同的結(jié)果輸出,概念有點(diǎn)繞,上代碼栗子:

function getDate() {
    return new Date();
}
var dateOne = getDate();
var dateTwo = getDate();
var dateThr = getDate();

上述代碼中調(diào)用了三次getDate(),三次返回的值都不一樣。相同的輸入并沒有相同的輸出,所以getDate()并不是一個純函數(shù)。

TIPS:函數(shù)中使用new Date(),Math.random(), 異步等都可能造成函數(shù)不穩(wěn)定。

沒有副作用(不改變外部環(huán)境的值)

部分小伙伴的代碼,在函數(shù)里面直接修改參數(shù)的值,這是一種非常不推薦的做法,這樣做會造成代碼環(huán)境不可控制,污染外部變量環(huán)境,一旦出現(xiàn)錯誤排查起來:心累,三個字心好累。

函數(shù)有自己的局部作用域,因此函數(shù)中,對需要使用到的變量,管控在自身的作用域下。如果需要修改外部參數(shù)的值,通過函數(shù)返回值返回給函數(shù)調(diào)用者。修改外部參數(shù)值的操作不在函數(shù)內(nèi)進(jìn)行,確保對外部環(huán)境沒有副作用。

TIPS:參數(shù)為引用類型時,參數(shù)復(fù)制的是地址指針,避免修改了引用類型中屬性值污染外部環(huán)境,如需使用建議手動深拷貝賦值。

function getGirlGift(list) {
    // 避免污染參數(shù)為引用類型的list,對list深拷貝
    var newList = JSON.parse(JSON.stringify(list));
    newList.map(girl => {
        girl.gift = girl.age > 18 ? "lipstick" : "chocolates";
    });
    return newList;    // 返回新值
}

var girlList = [
    {name: "Kelly", age: 20},
    {name: "Alic", age: 16},
    {name: "Moon", age: 23},
    {name: "Nana", age: 17}
];

var girlGiftList = getGirlGift(girlList);
girlList         // 原用girlList不變
girlGiftList     // 每個girl多了gift屬性
Array對象的函數(shù)(純與不純)
// 不純的函數(shù)
array.push();       // 數(shù)組尾部插入
array.pop();        // 刪除并返回數(shù)組最后一個元素
array.unshift();    // 數(shù)組頭部插入
array.shift();      // 刪除并返回數(shù)組第一元素
array.splice();     // 刪除元素,并向數(shù)組添加元素
array.reverse();    // 顛倒數(shù)組元素的順序
array.sort();       // 排序數(shù)組元素

// 純函數(shù)
array.slice();      // 數(shù)組中返回選定的元素
array.concat();     // 連接數(shù)組,并發(fā)揮新數(shù)組
array.join();       // 按分隔符連接數(shù)組,返回字符串

>>更多Array對象方法,參考W3C

純函數(shù)的應(yīng)用:狀態(tài)管理Redux,Vuex

流行框架中狀態(tài)管理就是純函數(shù)的實踐應(yīng)用,引用redux的應(yīng)用,reducer中返回新的狀態(tài)數(shù)據(jù)state,但不能去直接去修改state數(shù)據(jù),以下為redux中reducer的例子代碼:

export default (state = defaultState, action) => {
    let newState = JSON.parse(JSON.stringify(state));

    switch (action.type) {
        case DELETE_TODO_ITEM:
            newState.list.splice(action.value, 1);
        break;
        case ADD_TODO_ITEM:
            if (newState.inputValue.trim().length) {
                newState.list.push(newState.inputValue);
            }
            newState.inputValue = "";
        break;
        case INIT_LIST_ACTION: 
            newState = action.data
        break;
        default: 
        break;
    }

    return newState;
}
"自執(zhí)行函數(shù) +?閉包" 實現(xiàn)模塊化 模塊化包括:

私有變量

私有方法

公有變量

公有方法

上篇中《前端進(jìn)擊的巨人(三):從作用域走進(jìn)閉包》我們講解了作用域、閉包的原理機(jī)制。

"自執(zhí)行函數(shù)可實現(xiàn)塊級作用域,而閉包則可實現(xiàn)外部環(huán)境對函數(shù)作用域內(nèi)部數(shù)據(jù)的訪問。"

// 自執(zhí)行函數(shù) + 閉包實現(xiàn)模塊化
(function MakeModule(window) {
    var name = "以樂之名";
    var age = 28;
    var job = "程序員";
    
    function changeJob(newJob) {
        job = newJob;
    }
    
    function getName() {
        return name;        
    }
    
   window.modulePublic = {
        changeJob: changeJob,
        getName: getName
    }
})(window);

window.modulePublic.getName();
window.modulePublic.changeJob("產(chǎn)品經(jīng)理");

對作用域,以及閉包知識還沒掌握的小伙伴,可回閱《前端進(jìn)擊的巨人(三):從作用域走進(jìn)閉包》。

高階函數(shù)
高階函數(shù)是一個函數(shù),它接收函數(shù)作為參數(shù)或?qū)⒑瘮?shù)作為輸出返回

JavaScript中常用的高階函數(shù):

Array.prototype.map (映射遍歷)

Array.prototype.filter (過濾)

Array.prototype.reducer(累計)

除了內(nèi)置的高階函數(shù),我們實際開發(fā)中,高階函數(shù)應(yīng)用的最多就是回調(diào)函數(shù)了。

function getOrder(url, datas, callBack) {
    return $.post(url, datas, callBack(orderInfo));
}

// getOrder就是一個高階函數(shù),接收callBack函數(shù)作為參數(shù)

高階函數(shù)的概念很簡單,"本身是函數(shù),參數(shù)是函數(shù),或返回值是函數(shù)"

參考文檔:

JavaScript利用閉包實現(xiàn)模塊化

【翻譯】 - 淺談JavaScript中的高階函數(shù)

系列更文請關(guān)注專欄:《前端進(jìn)擊的巨人》,不斷更新中。。。

本文首發(fā)Github,期待Star!
https://github.com/ZengLingYong/blog

作者:以樂之名
本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請指明出處。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101284.html

相關(guān)文章

  • 前端進(jìn)擊巨人(六):知否知否,須知this

    摘要:有關(guān)函數(shù)柯里化的詳解,請回閱前端進(jìn)擊的巨人五學(xué)會函數(shù)柯里化。構(gòu)造函數(shù)中的通過操作符可以實現(xiàn)對函數(shù)的構(gòu)造調(diào)用。在了解構(gòu)造函數(shù)中的前,有必要先了解下實例化對象的過程。 showImg(https://segmentfault.com/img/bVburMp?w=800&h=600); 常見this的誤解 指向函數(shù)自身(源于this英文意思的誤解) 指向函數(shù)的詞法作用域(部分情況) th...

    Andrman 評論0 收藏0
  • 前端進(jìn)擊巨人(一):執(zhí)行上下文與執(zhí)行棧,變量對象

    摘要:在中,通過棧的存取方式來管理執(zhí)行上下文,我們可稱其為執(zhí)行棧,或函數(shù)調(diào)用棧。而處于棧頂?shù)氖钱?dāng)前正在執(zhí)行函數(shù)的執(zhí)行上下文,當(dāng)函數(shù)調(diào)用完成后,它就會從棧頂被推出理想的情況下,閉包會阻止該操作,閉包后續(xù)文章深入詳解。 寫在開篇 已經(jīng)不敢自稱前端小白,曾經(jīng)吹過的牛逼總要一點(diǎn)點(diǎn)去實現(xiàn)。 正如前領(lǐng)導(dǎo)說的,自己喝酒吹過的牛皮,跪著都得含著淚去實現(xiàn)。 那么沒有年終完美總結(jié),來個新年莽撞開始可好。 進(jìn)擊巨...

    _Suqin 評論0 收藏0
  • 前端進(jìn)擊巨人(七):走進(jìn)面向?qū)ο螅团c原型鏈,繼承方

    摘要:除了以上介紹的幾種對象創(chuàng)建方式,此外還有寄生構(gòu)造函數(shù)模式穩(wěn)妥構(gòu)造函數(shù)模式。 showImg(https://segmentfault.com/img/remote/1460000018196128); 面向?qū)ο?是以 對象 為中心的編程思想,它的思維方式是構(gòu)造。 面向?qū)ο?編程的三大特點(diǎn):封裝、繼承、多態(tài): 封裝:屬性方法的抽象 繼承:一個類繼承(復(fù)制)另一個類的屬性/方法 多態(tài):方...

    wums 評論0 收藏0
  • 前端進(jìn)擊巨人(五):學(xué)會函數(shù)柯里化(curry)

    摘要:函數(shù)柯里化是把支持多個參數(shù)的函數(shù)變成接收單一參數(shù)的函數(shù),并返回一個函數(shù)能接收處理剩余參數(shù),而反柯里化就是把參數(shù)全部釋放出來。但在一些復(fù)雜的業(yè)務(wù)邏輯封裝中,函數(shù)柯里化能夠為我們提供更好的應(yīng)對方案,讓我們的函數(shù)更具自由度和靈活性。 showImg(https://segmentfault.com/img/bVburN1?w=800&h=600); 柯里化(Curring, 以邏輯學(xué)家Has...

    chengtao1633 評論0 收藏0
  • 前端進(jìn)擊巨人(二):棧、堆、隊列、內(nèi)存空間

    摘要:中有三種數(shù)據(jù)結(jié)構(gòu)棧堆隊列。前端進(jìn)擊的巨人一執(zhí)行上下文與執(zhí)行棧,變量對象中解釋執(zhí)行棧時,舉了一個乒乓球盒子的例子,來演示棧的存取方式,這里再舉個栗子搭積木。對于基本類型,棧中存儲的就是它自身的值,所以新內(nèi)存空間存儲的也是一個值。 面試經(jīng)常遇到的深淺拷貝,事件輪詢,函數(shù)調(diào)用棧,閉包等容易出錯的題目,究其原因,都是跟JavaScript基礎(chǔ)知識不牢固有關(guān),下層地基沒打好,上層就是豆腐渣工程,...

    edgardeng 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<