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

資訊專欄INFORMATION COLUMN

【譯】為什么我更喜歡對(duì)象而不是switch語句

dack / 1747人閱讀

摘要:在本文中我將重點(diǎn)介紹第三種方式我更為喜歡的方法,即使用對(duì)象進(jìn)行快速地查找?,F(xiàn)在讓我們更實(shí)際一點(diǎn),不是我們寫的所有條件都會(huì)返回簡(jiǎn)單的字符串,其中很多會(huì)返回布爾值,執(zhí)行函數(shù)等等。

原文自工程師Enmanuel Durán博客,傳送門

最近(或者不是最近,這完全取決于您什么時(shí)候閱讀這邊文章),我正在跟我的團(tuán)隊(duì)伙伴討論如何去處理這種需要根據(jù)不同的值去處理不同的情況的方法,通常對(duì)于這種情況下,人們喜歡使用switch語句或者使用很多if搭配else if條件。在本文中我將重點(diǎn)介紹第三種方式(我更為喜歡的方法),即使用對(duì)象進(jìn)行快速地查找。

switch 語句

switch語句允許我們根據(jù)傳遞的表達(dá)式的值來執(zhí)行表達(dá)式并執(zhí)行某些特定的操作,通常當(dāng)你學(xué)習(xí)編寫代碼和算法時(shí),你會(huì)發(fā)現(xiàn)可以將它專門用于多種值的情況,你開始使用它,它看起來很好,你很快意識(shí)到它給了你很大的自由,耶!但是要小心,自由度越大責(zé)任感也就越大。

讓我們快速了解一下典型的switch語句是怎么樣的:

switch (expression) {
    case x: {
        /* Your code here */
        break;
    }
    case y: {
        /* Your code here */
        break;
    }
    default: {
        /* Your code here */
    }
}

很好,現(xiàn)在有一些你可能不知道需要注意的事情:

可選的關(guān)鍵字break

break關(guān)鍵字允許我們?cè)跐M足條件時(shí)停止執(zhí)行塊。如果不將break關(guān)鍵字添加到switch語句,則不會(huì)拋出錯(cuò)誤。如果我們不小心忘記break的話,可能意味著在執(zhí)行代碼的時(shí)候你甚至不知道代碼已經(jīng)正在執(zhí)行中了,這還會(huì)在調(diào)試問題時(shí)增加實(shí)現(xiàn)結(jié)果的的不一致性、突變、內(nèi)存泄漏和復(fù)雜度等問題。我們來看看這個(gè)問題的一種表示形式:

switch ("first") {
    case "first": {
        console.log("first case");
    }
    case "second": {
        console.log("second case");
    }
    case "third": {
        console.log("third case");
        break;
    }
    default: {
        console.log("infinite");
    }
}

如果你在控制臺(tái)中執(zhí)行這段代碼,你會(huì)看到輸出是

firt case
second case
third case

switch語句在第二種和第三種情況下也會(huì)執(zhí)行,即使第一種情況已經(jīng)是正確的,然后它在第三種情況塊中找到關(guān)鍵字break并停止執(zhí)行,控制臺(tái)中沒有警告或錯(cuò)誤讓你知道它,這會(huì)讓你認(rèn)為這是預(yù)期的行為。

每種情況下的大括號(hào)都不是強(qiáng)制的

在javascript中大括號(hào)代表著代碼塊,因?yàn)樽訣CMAscript 2015我們可以使用關(guān)鍵字聲明塊編譯變量,如const或let(但對(duì)于switch來說并不是很好),因?yàn)榇罄ㄌ?hào)不是強(qiáng)制性的,重復(fù)聲明會(huì)導(dǎo)致錯(cuò)誤變量,讓我們看看當(dāng)我們執(zhí)行下面的代碼時(shí)會(huì)發(fā)生什么:

switch ("second") {
    case "first":
        let position = "first";
        console.log(position);
        break;
    case "second":
        let position = "second";
        console.log(position);
        break;
    default:
        console.log("infinite");
}

我們會(huì)得到:

Uncaught SyntaxError: Identifier "position" has already been declared

這里將會(huì)返回一個(gè)錯(cuò)誤,因?yàn)樽兞縫osition已經(jīng)在第一種情況下聲明過了,并且由于它沒有大括號(hào),所以在第二種情況下嘗試聲明它,它已經(jīng)存在了。

現(xiàn)在想象使用帶有不一致break關(guān)鍵字和大括號(hào)的switch語句時(shí)會(huì)發(fā)生什么事:

switch ("first") {
    case "first":
        let position = "first";
        console.log(position);
    case "second":
        console.log(`second has access to ${position}`);
        position = "second";
        console.log(position);
    default:
        console.log("infinite");
}

控制臺(tái)將輸出以下內(nèi)容:

first
second has access to first
second
infinite

試想一下,由此而引起的錯(cuò)誤和突變是如此之多,其可能性是無窮無盡的……不管怎樣,switch語句已經(jīng)講夠了,我們來這里是為了討論一種不同的方法,我們來這里是為了討論對(duì)象。

更安全查找的對(duì)象

對(duì)象查找速度很快,隨著它們的大小增長它們也會(huì)更快,它們也允許我們將數(shù)據(jù)表示為對(duì)于條件執(zhí)行非常有用的鍵值對(duì)。

使用字符串

讓我們從簡(jiǎn)單的switch示例開始,讓我們假設(shè)我們需要有條件地保存和返回一個(gè)字符串的情景,并使用我們的對(duì)象:

const getPosition = position => {
    const positions = {
        first: "first",
        second: "second",
        third: "third",
        default: "infinite"
    };

    return positions[position] || positions.default;
};

const position = getPosition("first"); // Returns "first"
const otherValue = getPosition("fourth"); // Returns "infinite"

這可以做同樣類型的工作,如果你想進(jìn)一步的壓縮簡(jiǎn)化代碼,我們可以利用箭頭函數(shù):

const getPosition = position =>
    ({
        first: "first",
        second: "second",
        third: "third"
    }[position] || "infinite");

const positionValue = getPosition("first"); // Returns "first"
const otherValue = getPosition("fourth"); // Returns "infinite"

這與前面的實(shí)現(xiàn)完全相同,我們?cè)诟俚拇a行中實(shí)現(xiàn)了更緊湊的解決方案。

現(xiàn)在讓我們更實(shí)際一點(diǎn),不是我們寫的所有條件都會(huì)返回簡(jiǎn)單的字符串,其中很多會(huì)返回布爾值,執(zhí)行函數(shù)等等。

使用布爾值

我喜歡創(chuàng)建返回類型一致的值的函數(shù),但是,由于javascript是動(dòng)態(tài)類型語言,因此可能存在函數(shù)可能返回動(dòng)態(tài)類型的情況,因此我將在此示例中考慮這一點(diǎn),如果找不到鍵,我將創(chuàng)建一個(gè)返回布爾值,未定義或字符串的函數(shù)。

const isNotOpenSource = language =>
    ({
        vscode: false,
        sublimetext: true,
        neovim: false,
        fakeEditor: undefined
    }[language] || "unknown");

const sublimeState = isNotOpenSource("sublimetext"); // Returns true

看起來不錯(cuò),對(duì)吧?別急,好像我們有一個(gè)問題......如果我們調(diào)用帶有參數(shù)的函數(shù),會(huì)發(fā)生什么"vscode"或fakeEditor不是?嗯,讓我們來看看:

它會(huì)尋找對(duì)象中的鍵。

它會(huì)看到vscode鍵的值是false。

它會(huì)試圖返回false,但因?yàn)閒alse || "unknown"是unknown,我們最終會(huì)返回一個(gè)不正確的值。

對(duì)于key為fakeEditor也會(huì)有同樣的問題

Oh no, 好吧,不要驚慌,讓我們來解決這個(gè)問題:

const isNotOpenSource = editor => {
    const editors = {
        vscode: false,
        sublimetext: true,
        neovim: false,
        fakeEditor: undefined,
        default: "unknown"
    };

    return editor in editors ? editors[editor] : editors.default;
};

const codeState = isNotOpenSource("vscode"); // Returns false
const fakeEditorState = isNotOpenSource("fakeEditor"); // Returns undefined
const sublimeState = isNotOpenSource("sublimetext"); // Returns true
const webstormState = isNotOpenSource("webstorm"); // Returns "unknown"

這就解決了問題,但是......我希望你們問自己一件事:這真的是問題所在嗎?我認(rèn)為我們應(yīng)該更關(guān)心為什么我們需要一個(gè)返回布爾值,未定義值或字符串的函數(shù),這里存在嚴(yán)重的不一致性,無論如何,對(duì)于這樣一個(gè)非常棘手的情況這也只是一個(gè)可能的解決方案。

使用函數(shù)

我們繼續(xù)講函數(shù),通常我們會(huì)發(fā)現(xiàn)我們需要根據(jù)參數(shù)來執(zhí)行一個(gè)函數(shù),假設(shè)我們需要根據(jù)輸入的類型來解析一些輸入值,如果解析器沒有注冊(cè),我們只返回值:

const getParsedInputValue = type => {
    const emailParser = email => `email,  ${email}`;
    const passwordParser = password => `password, ${password}`;
    const birthdateParser = date => `date , ${date}`;

    const parsers = {
        email: emailParser,
        password: passwordParser,
        birthdate: birthdateParser,
        default: value => value
    };

    return parsers[type] || parsers.default;
};

// We select the parser with the type and then passed the dynamic value to parse
const parsedEmail = getParsedInputValue("email")("[email protected]"); // Returns email, [email protected]
const parsedName = getParsedInputValue("name")("Enmanuel"); // Returns "Enmanuel"

如果我們有一個(gè)類似的函數(shù)返回另一個(gè)函數(shù)但這次沒有參數(shù),我們可以改進(jìn)代碼,以便在調(diào)用第一個(gè)函數(shù)時(shí)直接返回,如:

const getValue = type => {
    const email = () => "[email protected]";
    const password = () => "12345";

    const parsers = {
        email,
        password,
        default: () => "default"
    };

    return (parsers[type] || parsers.default)(); // we immediately invoke the function here
};

const emailValue = getValue("email"); // Returns [email protected]
const passwordValue = getValue("name"); // Returns default
通用代碼塊

Switch語句允許我們?yōu)槎鄠€(gè)條件定義公共代碼塊。

switch (editor) {
    case "atom":
    case "sublime":
    case "vscode":
        return "It is a code editor";
        break;
    case "webstorm":
    case "pycharm":
        return "It is an IDE";
        break;
    default:
        return "unknown";
}

我們?nèi)绾问褂脤?duì)象來處理它?我們可以在下一個(gè)方面做到這一點(diǎn):

const getEditorType = type => {
    const itsCodeEditor = () => "It is a code editor";
    const itsIDE = () => "It is an IDE";

    const editors = {
        atom: itsCodeEditor,
        sublime: itsCodeEditor,
        vscode: itsCodeEditor,
        webstorm: itsIDE,
        pycharm: itsIDE,
        default: () => "unknown"
    };

    return (editors[type] || editors.default)();
};

const vscodeType = getEditorType("vscode"); 

現(xiàn)在我們有一種方法:

更有條理

更易拓展

更容易維護(hù)

更容易測(cè)試

更安全并且副作用和風(fēng)險(xiǎn)更小

注意事項(xiàng)

正如預(yù)期的那樣,所有的方法都有其缺點(diǎn),這一個(gè)也不例外。

由于我們正在使用對(duì)象,所以我們將占用內(nèi)存中的一些臨時(shí)空間來存儲(chǔ)它們,當(dāng)定義對(duì)象的作用域不再可訪問時(shí),這個(gè)空間將被垃圾收集器釋放。

當(dāng)沒有太多情況需要處理時(shí),對(duì)象方法可能比switch語句的速度要慢,這可能是因?yàn)槲覀冋趧?chuàng)建一個(gè)數(shù)據(jù)結(jié)構(gòu),然后接收一個(gè)鍵,然而在switch中,我們只是檢查值并返回值。

結(jié)論

本文不打算改變你的編碼風(fēng)格或讓你停止使用switch語句,它只是試圖提高你對(duì)switch語句的認(rèn)識(shí),以便它可以正確使用,并開放你的思想探索新的替代方案,在這種情況下,我已經(jīng)分享了我喜歡使用的方法,但還有更多,例如,你可能想看一個(gè)稱為模式匹配的ES6提案,如果你不喜歡它,你可以繼續(xù)探索。

好的開發(fā)未來,就是這樣,我希望你喜歡這篇文章,如果你這樣做,你可能會(huì)喜歡這篇關(guān)于工廠模式的文章。此外,不要忘記分享和點(diǎn)贊,你可以在twitter上找到我或通過我的電子郵件[email protected]聯(lián)系我,下一個(gè)見。

閱讀EnmaScript.com上發(fā)布的原始文章

譯者總結(jié)

本文介紹了一種使用對(duì)象去代替我們之前用switch和繁瑣的if else語句的方法。其實(shí),很多情況下我們可以利用對(duì)象與其他組合搭配寫出更為高效或可維護(hù)的代碼。當(dāng)然,如何去靈活地使用對(duì)象去處理一些對(duì)應(yīng)的情況,還是靠我們自己。好的,這篇就總結(jié)到這了,不知道對(duì)你們有什么啟發(fā)。相信會(huì)給到一些幫助給讀者,我們可不是一個(gè)只會(huì)if else的工程師,哈哈~

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

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

相關(guān)文章

  • 喜歡的5個(gè)編程技巧

    摘要:更多信息嵌套三元運(yùn)算符之前改造后我承認(rèn),一開始,使用嵌套三元運(yùn)算符的想法的確令人倒胃口。當(dāng)然使用三元運(yùn)算符具有兩面性,但就我個(gè)人而言,嵌套三元運(yùn)算符真的越來越吸引我了。 在這篇文章中,我介紹了一些編程時(shí)嘗試使用的模式。這些模式是多年來我自己在工作中實(shí)踐的結(jié)果,也有是從同事那里偷偷學(xué)到的。 這些模式?jīng)]有特定的順序,只是一個(gè)簡(jiǎn)單的集合。 提前退出(early exits) function...

    Aceyclee 評(píng)論0 收藏0
  • 」編寫更好的 JavaScript 條件式和匹配條件的技巧

    摘要:通常情況下,面向?qū)ο缶幊套屛覀兊靡员苊鈼l件式,并代之以繼承和多態(tài)。同時(shí),使用條件式簡(jiǎn)寫來表示值。因此,對(duì)于以這種方式編寫的代碼,你需要使用進(jìn)行編譯。 原文地址:Tips and Tricks for Better JavaScript Conditionals and Match Criteria 原文作者:Milos Protic 介紹 如果你像我一樣樂于見到整潔的代碼,那么你...

    honmaple 評(píng)論0 收藏0
  • [] JavaScript 性能優(yōu)化殺手

    摘要:原文引言這篇文檔包含了如何避免使代碼性能遠(yuǎn)低于預(yù)期的建議尤其是一些會(huì)導(dǎo)致牽涉到等無法優(yōu)化相關(guān)函數(shù)的問題一些背景在中并沒有解釋器但卻有兩個(gè)不同的編譯器通用編譯器和優(yōu)化編譯器這意味著你的代碼總是會(huì)被編譯為機(jī)器碼后直接運(yùn)行這樣一定很快咯并不是 原文:http://dev.zm1v1.com/2015/08/19/javascript-optimization-killers/引言 這篇文檔包...

    MockingBird 評(píng)論0 收藏0
  • [] Angular 屬性綁定更新機(jī)制

    摘要:本文主要介紹輸入輸出綁定方式,特別是當(dāng)父組件輸入綁定值變化時(shí),如何更新子組件輸入值。更新指令的屬性上文中已經(jīng)描述了函數(shù)是用來更新元素的屬性,而是用來更新子組件的輸入綁定屬性,并且變更檢測(cè)期間傳入的參數(shù)就是函數(shù)。 原文鏈接:The mechanics of property bindings update in Angular showImg(https://segmentfault....

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

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

0條評(píng)論

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