【Javascript】複数の関数を連続して実行する方法を試してみる
へんてこな?ことを試してます。意味不明だったらすみません。
概要
ある文字列が、ある複数の条件を満たしているかどうか判定したい。
1つ1つの条件判定は1つ1つ関数にするのだが、以下の2つの呼び出し方のどちらが速いか。
手順1 – 素直に1つずつ実行
ごく普通の風景。
function fn1(x){return "判定結果";} function fn2(x){return "判定結果";} function fn3(x){return "判定結果";} function fn4(x){return "判定結果";} function fn5(x){return "判定結果";} if (fn1(x) && fn2 (x) && fn3(x) && fn4(x) && fn5(x)) { //全部trueだったらOK } else { //ひとつでも途中でfalseだったらNG }
手順2 – 数珠つながりにしてfn1だけ呼べばよいようにする
関数の配列を作るなどするとおもしろい数珠つながりが作れる(後でやってみる)
function fn1(x){return "判定結果" && fn2(x);} function fn2(x){return "判定結果" && fn3(x);} function fn3(x){return "判定結果" && fn4(x);} function fn4(x){return "判定結果" && fn5(x);} function fn5(x){return "判定結果";} if (fn1(x)) { //trueだったら全部OKということ } else { //falseだったら途中でNGがあったということ }
実際にやりたいことに近いことをやってみる
なぜこんなことをしているかというと、ユーザーの入力に応じて判定条件を変えたいので、臨機応変に判定関数を組み合わせて実行したいから。
以下のサンプルコードの「/1/.test(x)」は、文字列xが文字”1″を含んでいればtrue、含んでいなければfalseが返ってくる(参考:RegExp.test)。
手順1のテスト
//判定関数を用意する(配列に入れておく。順次実行するときはfor文を使うことになる。) var fn = []; fn.push(function(x){return /1/.test(x);}); fn.push(function(x){return /2/.test(x);}); fn.push(function(x){return /3/.test(x);}); fn.push(function(x){return /4/.test(x);}); fn.push(function(x){return /5/.test(x);}); //100000回試すテスト var start = new Date().getTime(); for (var n = 0; n < 100000; ++n) { var hantei = true; var x = "123456789"; for (var i = 0, l = fn.length; i < l; ++i) { if (!fn[i](x)) { //falseが返ってきたら、判定中止 hantei = false; break; } } //hantei を見ると判定結果が分かる } var end = new Date().getTime(); alert(end - start);
結果 → 328ミリ秒
手順2のテスト
//判定関数を用意する(配列に入れておく。1つ目(fn[0])をキックすると数珠つながりに実行されるように仕掛けておく。) var fn = []; fn.push(function(x, i){return /1/.test(x) && fn[i + 1](x, i + 1);}); fn.push(function(x, i){return /2/.test(x) && fn[i + 1](x, i + 1);}); fn.push(function(x, i){return /3/.test(x) && fn[i + 1](x, i + 1);}); fn.push(function(x, i){return /4/.test(x) && fn[i + 1](x, i + 1);}); fn.push(function(x, i){return /5/.test(x);}); //100000回試すテスト var start = new Date().getTime(); for (var n = 0; n < 100000; ++n) { var x = "123456789"; var hantei = fn[0](x, 0); //hantei を見ると判定結果が分かる } var end = new Date().getTime(); alert(end - start);
結果 → 296ミリ秒
結果
数珠つながり方式が意外とまともに使えそうだった。
どこかですでに使われているだろうか。
コメント