読者です 読者をやめる 読者になる 読者になる

JavaScriptでswitch文を使わずに条件分岐

JavaScript

 JavaScriptでは関数もオブジェクトです。またJavaScript独自の特徴として、オブジェクトがそのままハッシュになります。なので、これを利用すると条件分岐が簡単に書けるようになります。
 これはHTML5APIやセレクトボックスで操作を切り替える場合のように、文字列で条件分岐したい。けど、Switch文のネストが複雑になりすぎる、あるいは不定数の選択肢に対して処理したいといった場合に便利です。

var  switching=function(key){
        var switchbox={};
        switchbox.a=function(){
          alert("a");
        }; 
        switchbox.b=function(){
            alert("b");
        };
        var func=switchbox[key];
        func();   
}

switching("a");//a
switching("b");//b


もちろん、外部から依存性を注入することも出来ます。

var switching(key,switchbox){
       
	var func=switchbox[key];
        func();   
};
var switchbox={};
switchbox.a=function(){
        alert("a");
}; 
switchbox.b=function(){
	alert("b");
};
switching("a",switchbox);//a
switching("b",switchbox);//b

switchbox.a=function(){
	alert("a->b");
}; 
swiwtchbox.b=function(){
		alert("b->a");
};
switching("a",switchbox);//a->b
switching("b",switchbox);//b->a

 ただし、分岐関数中でthisを使うような場合は注意が必要です

//×
var switching=function(key,switchbox){
	var func=switchbox[key];
        func();   
};
var switchbox=function(){};
switchbox.prototype.a=function(){
	alert(this.var_a);
}; 
switchbox.prototype.b=function(){
	alert(this.var_b);
};
switchbox.prototype.var_a=a; 
switchbox.prototype.var_b=b;
var box=new switchbox();
switching("a",box);//0
switching("b",box);//0

//○
var switching=function(key,switchbox){
       
	var func=switchbox[key];
        func.apply(switchbox);   
};

switching("a",box);//a
switching("b",box);//b


 javaScriptにおいてはthisは一定しません。obj.methodという静的な呼び方では他の言語と同じなのですが、今回のようにメンバ関数のみを動的に切り離して呼ぶ場合は異なってきます。詳しくはこちら
 なので、thisの動作を固定したい場合にはapplyまたはcallを使います。 applyとcallは関数オブジェクトのメソッドで、サンプルコードのように関数オブジェクトのメソッドとして呼び出します。
 一番最初の引数に内部ではthisとなる変数を指定します。例では省略していますが、applyの場合は二番目の引数は関数に与えたい引数をリストとして、callの場合は通常の場合と同じように並べて与えます。

 また、クロージャを利用するとこんなことも出来ます。

var switching=function(key){
    var test="c";
    var switchbox={};
    switchbox.a=function(){
         test="a";
    }; 
    switchbox.b=function(){
         test="b";
    };
    if(key!==undefined && key in switchbox){
         var func=switchbox[key];
         func();
    }
    alert(test);

};
switching();//c
switching("a");//a
switching("b");//b
switching("c");//c

 
 処理のネストが深い時にはクロージャを閉ざされたグローバル変数のように使い、フロントコントローラーとするとこれがなかなか。
 抽象化して汎用性を上げるのって、本当に楽しいですねぇ。

(追記)サンプルのバグとインデント修正しました