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

資訊專欄INFORMATION COLUMN

JavaScript函數(shù)式編程之管道分支,消除if/else的一種方式

IntMain / 2463人閱讀

摘要:在函數(shù)式編程中的錯誤處理,強壯代碼文章中所用的思路與本篇一樣,只不過在函數(shù)式編程中的錯誤處理,強壯代碼中可以認(rèn)為是以和作為標(biāo)識,而本篇多帶帶創(chuàng)造了標(biāo)識。使用本篇的方法重寫函數(shù)式編程中的錯誤處理,強壯代碼中的代碼參考資料函數(shù)式編程指南我在

以下代碼會用到函數(shù)組合函數(shù)compose,只要知道compose是干什么的就足夠了,如果好奇具體的實現(xiàn),可以看《JavaScript函數(shù)式編程之函數(shù)組合函數(shù)compose和pipe的實現(xiàn)》

管道是函數(shù)式編程中經(jīng)常使用的,很多時候我們需要按照條件判斷進(jìn)行組合函數(shù)的選擇,簡單的說就是從原來的一條管道變成兩條管道,根據(jù)判斷選擇進(jìn)入哪一條。

這里的關(guān)鍵在于,我們?nèi)绾闻袛嗌弦粋€函數(shù)的返回值應(yīng)該進(jìn)入哪一條管道?

let step1 = x => x ? 1 : 2;
let step2 = x => x === 1 ? 3 : 4;
let step3 = x => x === 3 ? 5 : 6;
let getResult = compose(step3, step2, step1)
let result = getResult(1);

這是最直接的方法,每一步根據(jù)返回值多帶帶判斷,如果step1的返回值發(fā)生了變化,下一步的判斷也需要跟著修改,這種寫法顯然不好。那我們能不能在返回值的基礎(chǔ)上加上一個標(biāo)識,專門用來做判斷?我們很自然的就會想到對象。

let step1 = x => {
  if (x) {
    return {
      value: 1,
      identity: "channelOne"
    }
  } else {
    return {
      value: 2,
      identity: "channelTwo"
    }
  }
}
let step2 = x => {
  if (x.identity === "channelOne") {
    return x.value = 3;
  } else {
    return x.value = 4;
  }
}
let step3 = x => {
  if (x.identity === "channelOne") {
    return x.value = 5;
  } else {
    return x.value = 6;
  }    
}
let getResult = compose(step3, step2, step1);
let result = getResult(1);

是不是好了很多?不過這依然要繼續(xù)改進(jìn)。當(dāng)我們需要使用forin等方式遍歷對象時,identity會被遍歷出來,一般情況下我們都希望它不會被遍歷,那就還需要把這個屬性定義為不可枚舉的。
修改step1并簡化代碼:

let step1 = x => {
  if (x) {
    let obj = {value: 1};
    Object.defineProperty(obj, "identity", {
      enumerable: false,
      value: "channelOne"
    });
    return obj;
  } else {
    let obj = {value: 2};
    Object.defineProperty(obj, "identity", {
      enumerable: false,
      value: "channelTwo"
    });
    return obj;
  }
}
let selectChannel = (fn1, fn2) => val => val.identity === "channelOne" ? fn1(val) : fn2(val);
let getResult = compose(
  selectChannel(
    x => Object.defineProperty(x, "value", {value: 5}),
    x => Object.defineProperty(x, "value", {value: 6})
  ),
  selectChannel(
    x => Object.defineProperty(x, "value", {value: 3}),
    x => Object.defineProperty(x, "value", {value: 4})
  ),
  step1
);
let result = getResult(1);

在selectChannel中,函數(shù)會根據(jù)傳進(jìn)來的對象的標(biāo)識選擇執(zhí)行。至此,功能基本上實現(xiàn)了,可依然不夠好,代碼不夠簡潔優(yōu)雅,重用也可以繼續(xù)改進(jìn)。

用構(gòu)造函數(shù)做標(biāo)識

let channelOne = function(x) { this.value = x; };
channelOne.of = x => new channelOne(x);
let channelTwo = function(x) { this.value = x; };
channelTwo.of = x => new channelTwo(x);
let step1 = x => x ? channelOne.of(1) : channelTwo.of(2);
let selectChannel = (fn1, fn2) => val => val.constructor === channelOne ? fn1(val) : fn2(val);
let getResult = compose(
  selectChannel(x => channelOne.of(5), x => channelTwo.of(6)),
  selectChannel(x => channelOne.of(3), x => channelTwo.of(4)),
  step1
);
let result = getResult(1);

太棒了!
看到這里,有么有驚喜的發(fā)現(xiàn),if/else不見了?肯定會有人覺得我是一個換湯不換藥的奸商。雖然if/else不見了,可是我用了三元運算符,這在本質(zhì)上有什么區(qū)別?
答案是,沒區(qū)別,他們都是條件判斷,這是不可避免的。
我們不妨?xí)簳r把關(guān)注的焦點放在三元運算符與if/else的區(qū)別上面來。我們什么時候會使用三元運算符?是條件判斷很簡單的時候,簡單到只需要一個表達(dá)式,而不是復(fù)雜的操作。雖然三元運算符也可以用逗號隔開表達(dá)式從而進(jìn)行多個操作,可我們這個時候更愿意使用if/else
說到這里就已經(jīng)很明顯了,這種構(gòu)造函數(shù)做標(biāo)識的方式,把復(fù)雜的條件判斷分解了,分解到在做判斷的時候只需要選擇方向,相關(guān)的操作可以扔到后面。

在《JavaScript函數(shù)式編程中的錯誤處理,強壯代碼》文章中所用的思路與本篇一樣,只不過在《JavaScript函數(shù)式編程中的錯誤處理,強壯代碼》中可以認(rèn)為是以nullundefined作為標(biāo)識,而本篇多帶帶創(chuàng)造了標(biāo)識。本篇中的方法更加的通用,因為nullundefined也可能是我們需要使用的值。

使用本篇的方法重寫《JavaScript函數(shù)式編程中的錯誤處理,強壯代碼》中的代碼

let channelError = function(x) { this.value = x; };
channelError.of = x => new channelError(x);
let channelSuccess = function(x) { this.value = x; };
channelSuccess.of = x => new channelSuccess(x);
let security= fn => val => val.constructor === channelError? val : fn(val);
let validate1 = x => x ? channelSuccess.of(x) : channelError.of("validate1 is not passed!");
let validate2 = x => x.value ? x : channelError.of("validate2 is not passed!");
let handleError = x => {
  if (x.constructor === channelError) alert(x.value);
};
let postData = () => axios.post(...);
let getResult = compose(
  handleError,
  security(postData),
  security(validate2),
  security(validate1)
);

參考資料:

JS函數(shù)式編程指南

我在github https://github.com/zhuanyongx...

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

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

相關(guān)文章

  • JavaScript函數(shù)編程入門經(jīng)典

    摘要:函數(shù)式編程的定義函數(shù)是一段可以通過其名稱被調(diào)用的代碼。純函數(shù)大多數(shù)函數(shù)式編程的好處來自于編寫純函數(shù),純函數(shù)是對給定的輸入返回相同的輸出的函數(shù),并且純函數(shù)不應(yīng)依賴任何外部變量,也不應(yīng)改變?nèi)魏瓮獠孔兞俊? 一個持續(xù)更新的github筆記,鏈接地址:Front-End-Basics,可以watch,也可以star。 此篇文章的地址:JavaScript函數(shù)式編程入門經(jīng)典 正文開始 什么是函...

    silvertheo 評論0 收藏0
  • 編程函數(shù)編程

    摘要:聲明式編程一種編程范式,與命令式編程相對立。常見的聲明式編程語言有數(shù)據(jù)庫查詢語言,正則表達(dá)式邏輯編程函數(shù)式編程組態(tài)管理系統(tǒng)等。函數(shù)式編程,特別是純函數(shù)式編程,嘗試最小化狀態(tài)帶來的副作用,因此被認(rèn)為是聲明式的。 編程范式與函數(shù)式編程 一、編程范式的分類 常見的編程范式有:函數(shù)式編程、程序編程、面向?qū)ο缶幊獭⒅噶钍骄幊痰取T诿嫦驅(qū)ο缶幊痰氖澜纾绦蚴且幌盗邢嗷プ饔茫ǚ椒ǎ┑膶ο螅–lass...

    noONE 評論0 收藏0
  • 編程 —— 函數(shù)編程入門

    摘要:在函數(shù)式編程中數(shù)據(jù)在由純函數(shù)組成的管道中傳遞。函數(shù)式編程中函子是實現(xiàn)了函數(shù)的容器下文中將函子視為范疇,模型可表示如下但是在函數(shù)式編程中要避免使用這種面向?qū)ο蟮木幊谭绞饺《畬ν獗┞读艘粋€的接口也稱為。 showImg(https://segmentfault.com/img/remote/1460000018101204); 該系列會有 3 篇文章,分別介紹什么是函數(shù)式編程、剖析函數(shù)...

    flyer_dev 評論0 收藏0
  • JavaScript 的未來:它還少些什么?

    摘要:例如通過哈希表映射需要一個操作來檢查值是否相等,另一個操作用于創(chuàng)建哈希碼。如果使用哈希碼,則對象應(yīng)該是不可變的。模式匹配提案目前處于第階段。在本文,我們研究其中的智能管道另一個提議被稱為。更強大,更重量級,并附帶自己的數(shù)據(jù)結(jié)構(gòu)。 翻譯:瘋狂的技術(shù)宅原文:http://2ality.com/2019/01/fut... 本文首發(fā)微信公眾號:jingchengyideng歡迎關(guān)注,每天...

    layman 評論0 收藏0
  • 編寫扁平化的代碼

    摘要:原文作者給你的代碼增加一點點函數(shù)式編程的特性最近我對函數(shù)式編程非常感興趣。對我而言,函數(shù)式編程最大的作用就是強制你編寫聲明性代碼代碼描述你做什么,而不是在描述如何做。事實證明,編寫聲明式代碼是函數(shù)式編程中最簡單的部分之一。 原文:Writing flat & declarative code作者:Peeke Kuepers -- 給你的代碼增加一點點函數(shù)式編程的特性 最近我對函數(shù)式編程...

    lunaticf 評論0 收藏0

發(fā)表評論

0條評論

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