JScript のプログラム フロー制御
通常、JScript スクリプトのステートメントは、記述された順序で実行されます。これは連続実行と呼ばれ、プログラム フローの既定の方法です。
連続実行の代わりに、プログラム フローをスクリプト内の他の部分に転送する方法があります。つまり、順序に従って次のステートメントを実行する代わりに、他のステートメントを実行します。
スクリプトを有効利用するには、このような制御転送を論理に行う必要があります。プログラム制御の転送は、結果をブール値 true または false で返す真理値ステートメントによる決定に基づいて行われます。式を作成した後、結果が真 (true) かどうかが評価されます。このような方法を利用できるプログラム構造は 2 種類あります。
1 つ目は選択構造です。これを使用すると、プログラムに分岐点を作成することによって、プログラム フローの流れを変更できます。JScript では次の 4 つの選択構造を使用できます。
- 単一選択構造 (if)
- 分岐選択構造 (if/else)
- 条件演算子 (?:)
- 複数選択構造 (switch)
プログラム制御構造の 2 つ目は、反復構造です。これを使用すると、ある条件が真 (true) である間、動作を繰り返す処理を指定できます。制御ステートメントの条件が満たされると (通常は指定した繰り返しの後)、制御は反復構造を抜けて次のステートメントに移ります。JScript では、次の 4 つの反復構造を使用できます。
- ループの最初に式が評価される (while)
- ループの最後に式が評価される (do/while)
- オブジェクトのプロパティごとに処理を行う (for/in)
- カウンタを使って反復を制御する (for)
選択制御構造や反復制御構造を入れ子にしたり重ねることによって、複雑なスクリプトを作成できます。
構造化されたプログラム フローの 3 つ目の形態は例外処理として提供されているため、このドキュメントでは説明を省きます。
条件ステートメントを使用する
JScript では、条件ステートメントとして if および if...else がサポートされています。if ステートメントで条件を評価すると、評価した条件が満たされる場合にだけ、なんらかの JScript コードが実行されます (if...else ステートメントの場合は、条件が満たされないときに別のコードが実行されます)。単純な if ステートメントの場合、全体を 1 行に収めて記述することもできます。一般には、if ステートメントや if...else ステートメントは複数の行にわたって記述されることになります。
次に、if ステートメント、および if...else ステートメントを使用したコードの例を示します。1 つ目の例は、単純にブール値の評価しています。かっこに囲まれた部分の評価結果が真 (true) の場合にのみ、if ステートメントの後ろのブロック内に記述されたステートメントを実行します。
// この例では、smash() 関数は同じコード内の別の場所で定義されているものとします。
// newShip が真かどうかを調べるため、ブール値を評価します。
if (newShip)
smash(champagneBottle,bow);
// この例では、両方の条件が真にならなければ、if ステートメントが真だとは見なされません。
if (rind.color == "濃い黄色 " && rind.texture == "大小のしわ付")
{
theResponse = ("それはクレンショーメロンですか?");
}
// この例では、2 つの条件のいずれかが真であれば、if ステートメントが真だと見なされます。
var theReaction = "";
if ((dayOfWeek == "土曜日") || (dayOfWeek == "日曜日"))
{
theReaction = ("浜辺に行くぞ!");
}
else
{
theReaction = ("ハイホー、ハイホー、仕事に戻らなくちゃ!");
}
条件演算子を使用する
JScript では、条件演算子もサポートされています。条件演算子では、疑問符の後ろにテストする条件を記述し (条件の前に if は記述しません)、その後ろに 2 種類の処理を指定します。この 2 種類の処理のうちの片方は条件が満たされる場合に使用されます。他方は条件が満たされない場合に使用されます。この 2 種類の処理は、コロンで区切ります。
var hours = "";
// このコードは、hours に theHour の値を入れるか、
// theHour - 12 の値を入れるかを調べています。
hours += (theHour >= 12) ? " PM" : " AM";
複数の条件を組み合わせて一緒に評価する場合、その中に結果を予測できる条件が含まれるときは、ショート サーキット評価と呼ばれる機能を使用することでスクリプトの実行速度を速くすることができます。JScript で論理式を評価する場合は、結果を取得するために必要なサブ条件が評価されるだけです。
たとえば、((x == 123) && (y == 42)) のような andAND 式がある場合、JScript では最初に x が 123 であるかを評価します。結果が偽の場合、y が 42 に等しい場合でも式全体は真 (true) にはなりません。そのため、y は評価されず、偽 (false) が返されます。
同様に、複数の条件のうちで 1 つでも真 (true) かどうかを評価するときは、|| 演算子を使います。|| 演算子を使うといずれか 1 つでも条件が真 (true) になった時点で評価処理が終了します。この調整は、評価する条件に関数の呼び出しや複雑な式が含まれている場合など、特に効果があります。ただし、Or 式を記述する場合は、必ず最初に true になりそうな条件を記述するようにしてください。また、And 式を記述する場合は、必ず最初に false になりそうな条件を記述するようにしてください。
この方法でスクリプトを作成した場合の利点は、次のコード例のように、runfirst() 関数が 0 を返すか、または偽 (false) である場合、runsecond() 関数を実行する必要がなくなる点です。
if ((runfirst() == 0) || (runsecond() == 0)) {
// some code
}
ループ
1 つのステートメントや複数のステートメントが入ったブロックを繰り返し実行する方法には、いくつかの種類があります。一般に、繰り返し実行は "ループ" または "反復処理" と呼ばれます。反復処理は、ループの 1 回の処理を実行します。通常、ループの制御は、ループ内の処理が実行されるたびに値が変化するなんらかの変数を評価して行います。JScript では、4 種類のループをサポートしています。for ループ、for...in ループ、while ループ、do...while ループです。
for ループ
for ステートメントには、カウンタ変数、評価する条件、およびカウンタを更新する処理を指定します。ループの反復が実行される前に、条件が評価されます。評価が成功した場合は、ループ内のコードが実行されます。評価が成功しなかった場合は、ループ内のコードは実行されず、次のループ内の 1 行目のコードの処理が続けられます。カウンタ変数は、ループの実行後、次の反復処理が開始される前に更新されます。
ループの条件が満たされない場合は、ループは一度も実行されません。条件が常に満たされ続けると、無限ループになってしまいます。ループに指定した条件が始めのうちは適切であっても、後から不適切となる場合があるので、ループ処理を記述するときは、注意してください。
/*
カウンタを更新する式 (下記の例では "icount++") は、
ループの最後に実行されます。ループに記述されたステートメントのブロックが実行された後、
条件が評価される前に実行されます。
*/
var howFar = 10; // ループの制限値を 10 に設定します。
var sum = new Array(howFar); // 0 から 9 までの 10 のメンバを持つ sum と呼ばれる配列を作成します。
var theSum = 0;
sum[0] = 0;
for(var icount = 0; icount < howFar; icount++) { // この場合のカウンタは、0 から 9 です。
theSum += icount;
sum[icount] = theSum;
}
var newSum = 0;
for(var icount = 0; icount > howFar; icount++) { // icount が howFar より大きいため、これは 1 度も実行されません。
newSum += icount;
}
var sum = 0;
for(var icount = 0; icount >= 0; icount++) { // これは無限ループです。
sum += icount;
}
for...in ループ
JScript では、オブジェクト内のすべてのユーザー定義プロパティ、または配列内のすべての要素を 1 つずつ処理するための特殊なループが用意されています。for...in ループのループ カウンタは、数値ではなく文字列です。現在のプロパティの名前または現在の配列要素のインデックスが含まれます。
次のコード例では、JScript にはない alert メソッドを使用しているので、Internet Explorer で実行するようにしてください。
// プロパティを持つオブジェクトを作成します。
var myObject = new Object();
myObject.name = "James";
myObject.age = "22";
myObject.phone = "555 1234";
// オブジェクトのすべてのプロパティを数えます。
for (prop in myObject)
{
// "プロパティ 'name' は James です。"と表示されます。
window.alert("プロパティ '" + prop + "' は " + myObject[prop] + "です。");
}
for...in ループは、VBScript の For Each...Next ループと似ていますが、動作は異なります。JScript の for...in loop は、JScript のオブジェクトのプロパティを対象として反復処理を行います。VBScript の For Each...Next ループは、コレクションの項目を対象として反復処理を行います。JScript のコレクション全体を対象に反復処理を行うには、Enumerator オブジェクトを使用する必要があります。Internet Explorer オブジェクトのように VBScript の For Each...Next と JScript の for...in ループの両方をサポートしているものもありますが、ほとんどのオブジェクトではサポートしていません。
while ループ
while ループは、for ループと似ています。ただし、for ループとは異なりカウンタ変数とカウンタを更新する処理がありません。ステートメントまたはステートメントのブロックの繰り返し処理を制御する際に、「あるコードを何回実行する」というような単純な規則よりさらに複雑な指定をする必要がある場合に、while ループを使用します。次のコードは、Internet Explorer オブジェクト モデルと while ループを使用して、ユーザーに簡単な質問をする例です。
var x = 0;
while ((x != 42) && (x != null))
{
x = window.prompt("好きな数字は何ですか?", x);
}
if (x == null)
window.alert("終了です!");
else
window.alert("最後の回答です!");
メモ while ループには、明示的なカウンタ変数がありません。このため、ほかの種類のループと比べても、無限ループに陥る可能性が高くなります。また、while ループを使用すると、ループを制御する条件がどこで更新されるのか判断しにくいため、条件が更新されないループを記述する可能性もあります。このような理由から while ループを使用したコードを記述する場合は、特に無限ループを作らないように注意してください。
また、JScript には while ループに似た do...while ループもあります。ただし、do...while ループは、条件がループの最初ではなく最後に評価されるため、少なくとも 1 回は必ず処理が実行されるという点で while ループとは異なります。上のコード例は、次のように書くこともできます。
var x = 0;
do
{
x = window.prompt("好きな数字は何ですか?", x);
} while ((x != 42) && (x != null));
if (x == null)
window.alert("終了です!");
else
window.alert("最後の回答です!");
break ステートメントと continue ステートメント
Microsoft JScript では、ある条件が満たされ、ループの実行を終了する場合に break ステートメントを使用します (break は、switch ブロックの終了にも使用できます)。continue ステートメントを使用すると、コード ブロックの残りの部分を実行しないでカウンタ変数を更新した後 (ただし、for または for...in の場合のみカウンタ変数の更新が行われます)、次の反復処理に移行できます。
次の例では、break ステートメントと continue ステートメントを使用して、上記の例のループを制御します。
var x = 0;
do
{
x = window.prompt("好きな数字は何ですか?", x);
// キャンセルされましたか?その場合、ループを終了します。
if (x == null)
break;
// 数字が入力されましたか?
// その場合、数値の入力は不要です。
if (Number(x) == x)
continue;
// ユーザーに数値の入力だけを促します。
window.alert("数値の入力だけを行ってください!");
} while (x != 42)
if (x == null)
window.alert("終了です!");
else
window.alert("最後の回答です!");