引数に呼び出す関数名を文字列で与えることにより、動的に呼び出す関数を変更することを考えます。
次のプログラムは、
if (i == 0) alert( 関数A() );
if (i == 1) alert( 関数B() );
と同じ処理です。関数Aも関数Bも引数をもっていません。
このとき、呼出し側の関数「例1」で、「関数A」「関数B」を文字列として扱い、実行時にその文字列により、呼び出す関数を動的に変更する方法を考えます。
function 関数A() { return ("関数Aを実行"); } function 関数B() { return ("関数Bを実行"); } function 例1() { var 関数名; for (var i = 0; i < 2; i++) { if (i == 0) 関数名 = "関数A"; if (i == 1) 関数名 = "関数B"; var 呼出関数 = new Function("return " + 関数名 + "()"); // 行A var 結果 = 呼出関数(); // 行B alert(結果); } }
関数名が「関数A」のとき、行Aは、
呼出関数 = new Function("return 関数A()");
となります。
これはFunctionコンストラクタにより「呼出関数」を定義したのです。
「return 関数A()」は、「関数Aの実行結果」であり、それに「呼出関数」という名称を付けています。
行Bは、「呼出関数」が関数であることから ( )を付けています。
すなわち、「結果」は「関数Aの実行結果」の値になります。
次のプログラムは、
if (i == 0) alert( 加算(10, 20) ); 30が表示される
if (i == 1) alert( 乗算(10, 20) ); 200が表示される
と同じ処理です。
function 加算(x, y) { return (x + y); } function 乗算(x, y) { return (x * y); } function 例2() { var 関数名; for (var i = 0; i < 2; i++) { if (i == 0) 関数名 = "加算"; if (i == 1) 関数名 = "乗算"; var 呼出関数 = new Function("引数1", "引数2", "return " + 関数名 + "(引数1, 引数2)"); var 結果 = 呼出関数(10, 20); alert(結果); } }
例1との本質的な違いは、引数があるかないかの違いだけです。
例1のnew Function("return 関数A()") を
new Function("x", "y", "return 関数A(x, y)")
のように、引数のリストを付け加えます。
なお、この場合、加算も乗算も引数が同じだったので、上述のようなプログラムになりましたが、引数の個数が異なると、プログラムは複雑になります。