jsでif-elseとswitchを置き換える方法

不言
リリース: 2018-07-16 09:56:49
オリジナル
4234 人が閲覧しました

この記事では主に js で if-else と switch を置き換える方法を紹介します。必要な方は参考にしてください。プロジェクトが比較的忙しい場合は、最初に実装が検討され、その時点で最適な方法でソリューションが実装されます。プロジェクトが忙しくない場合は、前のコードを見て、より良い実装ソリューションや最適化を考えます。プラン。著者も例外ではありません。特定の状況で if-else と switch を置き換える私の最近の解決策を読者に共有しましょう。何かアイデアがありましたら、コメント欄にメッセージを残してください。さらにコミュニケーションを深めましょう。

2. if-else の代わりにルックアップ テーブル

たとえば、次のような要件が発生する可能性があります。たとえば、特定のプラットフォームの信用スコア評価が 700 ~ 950 を超えている場合、それは優れた信用、650 を意味します。 -700 は信用度が高く、600 -650 は信用度が高く、550~600 は信用度が中程度、350~550 は信用度が低いです。

実装は非常に簡単です

実行には問題ありませんが、問題もあります

1.たとえば、650-750は優れた信用を意味します。 、750-950 は優れた信用を意味します。このように、メソッド全体を変更する必要があります。 jsでif-elseとswitchを置き換える方法

2. メソッドにはさまざまな魔法の数字があります: 700、650、600、550。今後のメンテナンスに支障が出る可能性がございます。

3. if-else が多すぎるので、少し強迫的に見えます

そこで、ルックアップテーブルを使用して構成データとビジネスロジックを分離しましょう

function showGrace(grace) {
    let _level='';
    if(grace>=700){
        _level='信用极好'
    }
    else if(grace>=650){
        _level='信用优秀'
    }
    else if(grace>=600){
        _level='信用良好'
    }
    else if(grace>=550){
        _level='信用中等'
    }
    else{
        _level='信用较差'
    }
    return _level;
}
ログイン後にコピー
このような修正の利点は、これを変更する必要があります。変更する必要があるのは、graceForLevel、levelText のみです。ビジネスロジックを変更する必要はありません。

ここで構成データとビジネス ロジックを分離することが推奨される理由

1. 構成データの変更は、ビジネス ロジックを変更するよりもコストが低く、リスクが低いです

2. 構成データ ソースと変更は非常に柔軟です

3.論理的に分離すると、変更が必要なコードをより速く見つけることができます

より柔軟にしたい場合は、もう少し一般的な検索関数をカプセル化できます。

function showGrace(grace) {
    let graceForLevel=[700,650,600,550];
    let levelText=['信用极好','信用优秀','信用良好','信用中等','信用较差'];
    for(let i=0;i<graceforlevel.length>=graceForLevel[i]){
            return levelText[i];
        }
    }
    //如果不存在,那么就是分数很低,返回最后一个
    return levelText[levelText.length-1];
}</graceforlevel.length>
ログイン後にコピー

推奨される構成データとビジネス ロジック分離フォームの開発を使用すると、上記の例には反映されていない別の利点があります。以下で簡単に説明します。たとえば、アトラクションに入り、そのアトラクションがある都市を指定します。

function showGrace(grace,level,levelForGrace) {
    for(let i=0;i<level.length>=level[i]){
            return levelForGrace[i];
        }
    }
    //如果不存在,那么就是分数很低,返回最后一个
    return levelForGrace[levelText.length-1];
}
let graceForLevel=[700,650,600,550];
let levelText=['信用极好','信用优秀','信用良好','信用中等','信用较差'];</level.length>
ログイン後にコピー

広州塔に入り、広州に戻ります。西湖に入り杭州に戻ります。しかし、都市には複数の魅力があるため、このように書くことに慣れている人もいます。 jsでif-elseとswitchを置き換える方法

function getCityForScenic(scenic) {
    let _city=''
    if(scenic==='广州塔'){
        _city='广州'
    }
    else if(scenic==='西湖'){
        _city='杭州'
    }
    return _city;
}
ログイン後にコピー
アトラクションが多くてデータが非常に長い場合、このように書くのが好きな人もいます

if(scenic==='广州塔'||scenic==='花城广场'||scenic==='白云山'){
    _city='广州'
}
ログイン後にコピー

これは正しいですが、書かれたコードは次のようになります

スタイルは次のとおりです。均一ではありません

jsでif-elseとswitchを置き換える方法

let scenicOfHangZhou=['西湖','湘湖','砂之船生活广场','京杭大运河','南宋御街']
if(~scenicOfHangZhou.indexOf(scenic)){
    _city='杭州'
}
ログイン後にコピー
switchを使っていても、そのような状況が起こる可能性があります

function getCityForScenic(scenic) {
    let _city='';
    let scenicOfHangZhou=['西湖','湘湖','砂之船生活广场','京杭大运河','南宋御街'];
    if(scenic==='广州塔'||scenic==='花城广场'||scenic==='白云山'){
        _city='广州'
    }
    else if(~scenicOfHangZhou.indexOf(scenic)){
        _city='杭州'
    }
    return _city;
}
ログイン後にコピー
上記のコードが現れる確率は非常に低いですが、結局は起こります。このようなコードは将来混乱を引き起こす可能性があります。この問題は、構成データとビジネスロジックを分離すれば回避できます。
function getCityForScenic(scenic) {
    let _city='';
    let scenicOfHangZhou=['西湖','湘湖','砂之船生活广场','京杭大运河','南宋御街'];
    switch(true){
        case (scenic==='广州塔'||scenic==='花城广场'||scenic==='白云山'):_city='广州';break;
        case (!!~scenicOfHangZhou.indexOf(scenic)):return '杭州';   
    }
    return     _city;
}
ログイン後にコピー
オブジェクトのキー名が中国語であることに慣れていない人もいます。柔軟な対応も可能です

function getCityForScenic(scenic) {
    let cityConfig={
        '广州塔':'广州',
        '花城广场':'广州',
        '白云山':'广州',
        '西湖':'杭州',
        '湘湖':'杭州',
        '京杭大运河':'杭州',
        '砂之船生活广场':'杭州',
        '南宋御街':'杭州',
    }
    
    return cityConfig[scenic];
}
ログイン後にコピー
このように、将来的にアトラクションや対応する都市を追加したい場合は、上記のcityConfigを変更するだけで済み、ビジネスロジックを変更する必要はなく、変更することもできませんかわった。コーディングスタイルは統一されています。

構成データとビジネスロジックを分離する形式を使用した利点を簡単にまとめます

構成データの変更は、ビジネスロジックを変更するよりもコストとリスクが低くなります

  1. 構成のソースと変更データを簡単に柔軟にできます

  2. 構成とビジネスロジックを分離すると、変更が必要なコードをすぐに見つけることができます

  3. データとビジネスロジックを構成すると、コードスタイルを統一できます

  4. しかし、すべてが if-else であるわけではありませんではそのような変換を推奨していますが、必要に応じてルックアップ変換を使用することは推奨されません。たとえば、if-else の数が少なく、if 判定のロジックが一律に使用されていない場合でも、if-else メソッドを使用することをお勧めします。ただし、マジックナンバーをクリアする必要があります。

    たとえば、次の例では、受信タイムスタンプが不要になり、コメント時間が表示されます。
1 時間以内にコメントを公開: x 分前

1 時間から 24 時間前にコメントを公開: レビューが 24 時間投稿されました。 ~ 30 日前: 難しいですが、if-else をいくつかだけで十分です

function getCityForScenic(scenic) {
    let cityConfig=[
        {
            scenic:'广州塔',
            city:'广州'
        },
        {
            scenic:'花城广场',
            city:'广州'
        },
        {
            scenic:'白云山',
            city:'广州'
        },
        {
            scenic:'西湖',
            city:'杭州'
        },
        {
            scenic:'湘湖',
            city:'杭州'
        },
        {
            scenic:'京杭大运河',
            city:'杭州'
        },
        {
            scenic:'砂之船生活广场',
            city:'杭州'
        }
    ]
    for(let i=0;i<cityconfig.length><p><strong><p>运行结果没问题,但是也存在一个问题,就是这个需求有神仙数字:2592000000,86400000,3600000,60000。对于后面维护而言,一开始可能并不知道这个数字是什么东西。</p>
<p>所以下面就消灭神仙数字,常量化</p>
<pre class="brush:php;toolbar:false">function formatDate(timeStr){
    //获取当前时间戳
    let _now=+new Date();
    //求与当前的时间差
    let se=_now-timeStr;
    const DATE_LEVEL={
      month:2592000000,
      day:86400000,
      hour:3600000,
      minter:60000,
    }
    let _text='';
    //去年
    if(new Date(timeStr).getFullYear()!==new Date().getFullYear()&&se>DATE_LEVEL.month){
      _text=new Date(timeStr).getFullYear()+'年'+(new Date(timeStr).getMonth()+1)+'月'+new Date(timeStr).getDate()+'日';
    }
    //一个月以上
    else if(se>DATE_LEVEL.month){
      _text=(new Date(timeStr).getMonth()+1)+'月'+new Date(timeStr).getDate()+'日';
    }
    //一天以上
    else if(se>DATE_LEVEL.day){
      _text=Math.floor(se/DATE_LEVEL.day)+'天前';
    }
    //一个小时以上
    else if(se>DATE_LEVEL.hour){
      _text=Math.floor(se/DATE_LEVEL.hour)+'小时前';
    }
    //一个小时以内
    else{
      //如果小于1分钟,就显示1分钟前
      if(se<date_level.minter><p>运行结果也是正确的,代码多了,但是神仙数字没了。可读性也不差。</p>
<blockquote>这里也顺便提一下,如果硬要把上面的需求改成look-up的方式,代码就是下面这样。这样代码的修改的扩展性会强一些,成本会小一些,但是可读性不如上面。取舍关系,实际情况,实际分析。</blockquote>
<pre class="brush:php;toolbar:false">function formatDate(timeStr){
    //获取当前时间戳
    let _now=+new Date();
    //求与当前的时间差
    let se=_now-timeStr;
    let _text='';
    //求上一年最后一秒的时间戳
    let lastYearTime=new Date(new Date().getFullYear()+'-01-01 00:00:00')-1;
    //把时间差添加进去(当前时间戳与上一年最后一秒的时间戳的差)添加进去,如果时间差(se)超过这个值,则代表了这个时间是上一年的时间。
    //DATE_LEVEL.unshift(_now-lastYearTime);
    const DATE_LEVEL={
      month:2592000000,
      day:86400000,
      hour:3600000,
      minter:60000,
    }
    let handleFn=[
        {
            time:DATE_LEVEL.month,
            fn:function(timeStr){
                return (new Date(timeStr).getMonth()+1)+'月'+new Date(timeStr).getDate()+'日';
            }
        },
        {
            time:DATE_LEVEL.day,
            fn:function(timeStr){
                return Math.floor(se/DATE_LEVEL.day)+'天前';
            }
        },
        {
            time:DATE_LEVEL.hour,
            fn:function(timeStr){
                return Math.floor(se/DATE_LEVEL.hour)+'小时前';
            }
        },
        {
            time:DATE_LEVEL.minter,
            fn:function(timeStr){
                return Math.ceil(se/DATE_LEVEL.minter)+'分钟前';
            }
        } 
    ];
    //求上一年最后一秒的时间戳
    let lastYearTime=new Date(new Date().getFullYear()+'-01-01 00:00:00')-1;
    //把时间差(当前时间戳与上一年最后一秒的时间戳的差)和操作函数添加进去,如果时间差(se)超过这个值,则代表了这个时间是上一年的时间。
    handleFn.unshift({
        time:_now-lastYearTime,
        fn:function(timeStr){
            if(se>DATE_LEVEL.month){
                return new Date(timeStr).getFullYear()+'年'+(new Date(timeStr).getMonth()+1)+'月'+new Date(timeStr).getDate()+'日';
                
            }
        },
    });
    let result='';
    for(let i=0;i<handlefn.length>=handleFn[i].time){
            result=handleFn[i].fn(timeStr);
            if(result){
                return result;
            }
        }
    }
    //如果发布时间小于1分钟,之际返回1分钟
    return result='1分钟前'
}</handlefn.length>
ログイン後にコピー

3.配置对象代替switch

比如有一个需求:传入cash,check,draft,zfb,wx_pay,对应输出:现金,支票,汇票,支付宝,微信支付。

需求也很简单,就一个switch就搞定了

function getPayChanne(tag){
    switch(tag){
        case 'cash':return '现金';
        case 'check':return '支票';
        case 'draft':return '汇票';
        case 'zfb':return '支付宝';
        case 'wx_pay':return '微信支付';
    }
}
ログイン後にコピー

jsでif-elseとswitchを置き換える方法

但是这个的硬伤还是和上面一样,万一下次又要多加一个如:bank_trans对应输出银行转账呢,代码又要改。类似的问题,同样的解决方案,配置数据和业务逻辑分离。代码如下。

function getPayChanne(tag){
    let payChanneForChinese = {
        'cash': '现金',
        'check': '支票',
        'draft': '汇票',
        'zfb': '支付宝',
        'wx_pay': '微信支付',
    };
    return payChanneForChinese[tag];
}
ログイン後にコピー

同理,如果想封装一个通用的,也可以的

let payChanneForChinese = {
    'cash': '现金',
    'check': '支票',
    'draft': '汇票',
    'zfb': '支付宝',
    'wx_pay': '微信支付',
};
function getPayChanne(tag,chineseConfig){
    return chineseConfig[tag];
}
getPayChanne('cash',payChanneForChinese);
ログイン後にコピー

这里使用对象代替 switch 好处就在于

  1. 使用对象不需要 switch 逐个 case 遍历判断。

  2. 使用对象,编写业务逻辑可能更灵活

  3. 使用对象可以使得配置数据和业务逻辑分离。好处参考上一部分内容。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

以上がjsでif-elseとswitchを置き換える方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!