t_uda t_uda 2014-04-22 23:13:04

[JavaScript] switch (true) このエントリーをはてなブックマークに追加

投稿者からのアピールポイント

どうやらこのイディオム (????) には 賛否両論 あるらしいということは知っていますが,敢えて投稿してみます.皆さんの忌憚ないご意見を頂ければと思います.

(色々思うところがあるので,あとで Qiita 辺りに考察記事を書こうと思っています.頂いたご意見は引用させていただくかもしれません.)

function hoge(x) {
    switch (true) {
    case x < 0:
        console.log(x + " は自然数ではありません.");
        break;
    case x === 0:
        console.log("ここでは 0 は自然数です.");
        break;
    case x > 0:
        console.log(x + " は正の数です.");
        break;
    default:
        console.log(x + " は数ではないようです.");
    }
}

使い方ヒント: 「これは臭う」という行を見付けたら、各行のsmellをクリックしてマーキングしておきましょう(要Twitter OAuth認証)

コメント(12)

#1 Hikaru_oao Hikaru_oao 2014-04-23 14:19:15  

これは大有りです。 立派なテクニックの1つです。 ただしこの例だとif-elseで十分ですね。

#2 t_uda t_uda 2014-04-25 16:37:16  

@Hikaru_oao 「if-else」では不十分で,「switch(true)」が有効に働く例を教えて頂けないでしょうか?よろしくお願いします.

#3 sharo0331 sharo0331 2014-04-25 16:40:59  

1つのオブジェクトに対する条件分岐にはよく使えそうだね。 これからこの技使ってみようと思います

#6 tkcomcom1is tkcomcom1is 2014-04-27 21:19:24  

賛成反対かと言われるとどちらともいえないです。
理由としては結構表面的ですが、こんな感じです。

賛成理由:可読性がif-elseより良いから。
完全に主観ですが、最初だけifで、残りがelse ifだと、スペースを入れないと条件式のインデントが揃わなくて見づらいです。
反対理由:汎用的な書き方でないから。
今回のサンプルではJavaScriptですが、Cとか古いバージョンのJavaではこんな書き方はできません。

JavaScriptだとif-elseとswitchの速度差ってどうなのかなと思いましたが、このサイトにこんなコメントがありました。
大量の条件分岐を是としないなら、速度差がないというのも仕方ないとは思いますが。
・[JavaScript] とっても長いswitch/case文
http://unkode-mania.net/view/5018ddaa7e19b40f5a000002#comment_502b631a7d7552964c000010

「if-else」では不十分で,「switch(true)」が有効に働く例を教えて頂けないでしょうか?よろしくお願いします.
横やりで失礼しますが、「ラベル」で調べてみるとよいと思います。
・switch文 - Wikipedia
http://ja.wikipedia.org/wiki/Switch%E6%96%87
・テーブルジャンプ - Wikipedia
http://ja.wikipedia.org/wiki/%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%B8%E3%83%A3%E3%83%B3%E3%83%97
・ラベル (プログラミング) - Wikipedia
http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%99%E3%83%AB_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

Qiitaを拝見しました。
少し思うところがあるので、述べさせていただきます。

true の評価結果(??)によって場合分けする.
この不自然な直訳こそが,「switch 本来の意味からかけ離れているためにコードの意図が分かりづらくなっている」という主張の正体です.」
とありますが、それなら無限ループの常套句である
while(true) { ... }
「while本来の使い方じゃないから分かりづらい」という主張になるはずですが、どうでしょうか?

また、
個々人が見慣れているかどうかは些細な問題であると考えています.
ともありますが、それだとしたら、些細な問題とみなせるのはどの程度かを考慮すべきです。
例えば極端な話、プログラミング未体験の人とベテランのプログラマーが同じHello, world!を表示させるプログラムを見る場面を考えたら、分かるかと思います。
議論を深入りさせるのは不毛なので主張は述べませんが、どうも「理解できない」と「思考を停止する」を混同して使われているように見受けられました。

#7 t_uda t_uda 2014-04-28 20:14:50  

@tkcomcom1is 複数のコメントありがとうございます.

JavaScriptだとif-elseとswitchの速度差ってどうなのかなと思いましたが、このサイトにこんなコメントがありました。

巨大 switch のところ,一通り見ましたが,ジャンプがうまく働いているために switch の方が速い例だと思います(確証はないですが).しかし,残念ながら switch(true) だとテーブルジャンプの恩恵は受けられないのではないでしょうか.(…と,思うのですが,ラベルで調べるとホントにそんな例が出てくるんでしょうか?もちろんラベルのこともテーブルジャンプのことも知っていますが,そこはちょっと仰りたいことがよく分かりませんでした.)

「while本来の使い方じゃないから分かりづらい」という主張になるはずですが、どうでしょうか?

while(true) について,何人かそのような意見を仰る人がいます(Qiita でも同様のコメントがついています)が,私は的外れだと思っています.というのは,while(true) は「無限ループさせる」という意図と利点が明確だからです.Qiita の記事では,「本来の使い方じゃないから分かりづらい」ことの他に「そのイディオムの利点が明確であるかどうか」も問題にしています.while(true) は「無限ループできる」という利点が明確ですから,switch(true) とは比較できないでしょう.

それだとしたら、些細な問題とみなせるのはどの程度かを考慮すべきです。 どうも「理解できない」と「思考を停止する」を混同して使われているように見受けられました。

うーん,確かにそうかもしれません.この辺りの考察はまだ詰め切れていなかったようです.ご指摘感謝します.

#8 t_uda t_uda 2014-04-28 20:16:00  

(このサイト blockquote 分かりづらいな…)

#9 jkr_2255 jkr_2255 2014-06-29 23:12:21  

RubyとかSQLではcase-whenだけど、それらの言語だと「case when 条件式(後略)」という形で、trueすら書かずに同等のことを実現できるんだよなあ。

#10 BlufeNT BlufeNT 2014-09-03 00:24:39  

trueであるcaseにswitchするという明確な文法になっているのでバッドノウハウとまでは言わないと思う。

しかし大抵の言語にある文法て、その言語特有の仕様を使うのは、綺麗に書けるから、だけではリスクとのバランスが取れないと思います。 上記のようにそれしか処理がない関数なら、関数自体の目的が非常に明確なので、ありだと思います。

#12 risunosuke risunosuke 2014-10-03 13:54:58  

PHPのコードを見ているつもりで、「これのどこがウンコードなんだよ?」と思ってしまいました。 JavaScriptでしたね。

コメント投稿には、twitter認証が必要です。

Twitter認証

このウンコードに臭った人は、こちらのウンコードにも臭ってます

[Java] 連番

このエントリーをはてなブックマークに追加

もはや人間が読むものではない。

...

package com.renban.erq053.czp008;

/**...

鑑賞する »

[JavaScript] これではまった

このエントリーをはてなブックマークに追加

しばらくなやんだよ。なんでだよといいたか...

var a=b=3,//これはOK
before=result=new Arr...

鑑賞する »

[JavaScript] void function

このエントリーをはてなブックマークに追加

『なんでエラーが出るの!?』

void function unko(nihoi,sonota){
 aler...

鑑賞する »