Statements リダイレクト 1

JavaScript は、Web ページに多くのインタラクティビティを組み入れることを可能にする、コンパクトな文のセットをサポートします。この章では、これらの文の概要を説明します。

あらゆる式は、文でもあります。文に関する網羅的な情報については Expressions and Operators を参照してください。

JavaScript のコードでは、セミコロン (;) 文字で文を区切ります。

この章の文に関する詳細については JavaScript リファレンスをご覧ください。

ブロック文

ブロック文は、文のグループ化に用います。ブロックは、波括弧のペアで区切ります:

{
   statement_1;
   statement_2;
   .
   .
   .
   statement_n;
}


ブロック文は一般に、制御フロー文 (例: ifforwhile) で用いられます。

while (x < 10){
  x++;
}

ここでは { x++; } がブロック文です。

重要: JavaScript にはブロックスコープがありません。ブロック内で導入された変数のスコープは、そのブロックがある関数やスクリプトになります。また変数をセットすることの影響は、そのブロックを越えて持続されます。つまり、ブロック文はスコープを持ち込まないということです。"独立した" ブロックも正しい構文ですが、C や Java のブロックで果たされるような機能を期待しているのであれば、そのような機能を果たさないことから、JavaScript で独立したブロックを使う必要はありません。例えば:

var x = 1;
{
  var x = 2;
}
alert(x); // 2 を出力

ブロック内の var x 文はブロックの前の var x 文と同じスコープ内であるため、この例では 2が出力されます。C や Java では、同等のコードで 1 が出力されます。

条件文

条件文は、指定した条件が true ならば実行されるコマンドのセットです。JavaScript は if...elseswitch の 2 つの条件文をサポートしています。

if...else 文

ある論理条件が true ならばある文を実行したいときは、if 文を使用してください。オプションの else 節を使用すると、条件が false の場合にある文を実行することができます。if 文は次のように使用します:

if (condition)
  statement_1
[else
  statement_2]

condition には、true か false に評価される式が入ります。condition が true に評価された場合は statement_1 が実行され、そうでない場合は statement_2 が実行されます。statement_1statement_2 はどのような文でもかまいません。if をさらに入れ子にすることもできます。

次のように else if を使用して文を重ねることで、複数の条件を順々にテストすることができます:

if (condition)
  statement_1
[else if (condition_2)
  statement_2]
...
[else if (condition_n_1)
  statement_n_1]
[else
  statement_n]

複数の文を実行するには、ブロック文 ({ ... }) を使用してその文をグループ化してください。一般に、常にブロック文を使用するのが優れた方法です。特に if 文を入れ子にしたコードで有効です:

if (condition) {
  statements_1
} else {
  statements_2
}

条件式では単純な代入を使用しないようにしてください。コードを一見した際に、代入を等価条件と見間違えるおそれがあるためです。例えば、次のようなコードは使用しないでください:

if (x = y) {
  /* 正しいことをする */
}

条件式で代入を行う必要がある場合の一般的な方法は、代入式をさらに括弧でくくることです。例えば:

if ((x = y)) {
  /* 正しいことをする */
}

以下の値は false に評価されます:

  • false
  • undefined
  • null
  • 0
  • NaN
  • 空の文字列 ("")

オブジェクトを含む上記以外すべての値は、条件文に渡されると trune に評価されます。

プリミティブな真偽値の truefalse を、Boolean オブジェクトの true や false という値と混同しないでください。例えば:

var b = new Boolean(false);
if (b) // この条件は true に評価される


次の例で、関数 checkDataText オブジェクトに含まれている文字数が 3 である場合に true を返し、そうでない場合はアラートを表示して false を返します。

function checkData() {
  if (document.form1.threeChar.value.length == 3) {
    return true;
  } else {
    alert("Enter exactly three characters. " +
      document.form1.threeChar.value + " is not valid.");
    return false;
  }
}

switch 文

switch 文を使うと、プログラムは式を実行し、式の値を case ラベルと照合します。マッチすると、プログラムは結びつけられた文を実行します。switch 文は次のように使用します:

switch (expression) {
   case label_1:
      statements_1
      [break;]
   case label_2:
      statements_2
      [break;]
   ...
   default:
      statements_def
      [break;]
}

プログラムはまず、式の値にマッチしたラベルを持つ case 節を探します。そして制御をその節に移し、結びつけられた文を実行します。マッチしたラベルがない場合、プログラムはオプションの default 節を探し、存在する場合はその節に制御を移し、結びつけられた文を実行します。default 節がない場合、プログラムは switch 文の後に続く文を実行し続けます。慣例により、default 節は最後の節にします。しかし、そうしなければいけないわけではありません。

case に結びつけられたオプションの break 文は、マッチした文を実行したら switch 文から抜けて、switch 文に続く文を実行し続けることを確実にするものです。break を省略した場合、プログラムはその switch 文内における次の文から実行し続けます。


次の例では、fruittype が "Bananas" に評価された場合は case "Bananas" にマッチして、それに結びつけられた文を実行します。break 文に出くわすとプログラムは switch から抜けて、switch の後に続く文を実行します。break を省略すると、case "Cherries" の文も実行されます。

switch (fruittype) {
   case "Oranges":
      document.write("Oranges are $0.59 a pound.<br>");
      break;
   case "Apples":
      document.write("Apples are $0.32 a pound.<br>");
      break;
   case "Bananas":
      document.write("Bananas are $0.48 a pound.<br>");
      break;
   case "Cherries":
      document.write("Cherries are $3.00 a pound.<br>");
      break;
   case "Mangoes":
   case "Papayas":
      document.write("Mangoes and papayas are $2.79 a pound.<br>");
      break;
   default:
      document.write("Sorry, we are out of " + fruittype + ".<br>");
}
document.write("Is there anything else you'd like?<br>");

ループ文

ループは、指定された条件が満たされている限り繰り返し実行されるコマンドのセットです。JavaScript は fordo whilewhile といったループ文や、label (label 自体はループ文ではありませんが、これらの文とともに頻繁に使用されます) をサポートしています。さらに break および continue 文をループ文の中で使用することができます。

また for...in 文も文を繰り返し実行しますが、これはオブジェクトの操作に使用します。オブジェクト操作文をご覧ください。

ループ文は以下のとおりです:

for 文

for ループは、指定した条件が false に評価されるまで繰り返します。JavaScript の for ループは Java や C の for ループに似ています。for 文は次のように使用します:

for ([initialExpression]; [condition]; [incrementExpression])
   statement

for ループを実行すると以下のことが起こります:

  1. 初期化式 initialExpression を、あれば実行します。この式は通常、1 つかそれ以上のループカウンタを初期化しますが、構文上はあらゆる複雑な式も指定できます。また、この式は変数を宣言することもできます。
  2. condition 式を評価します。condition の値が true であれば、ループ文を実行します。condition の値が false であれば、for ループを終了します。condition 式が完全に省略されている場合、条件は true であると仮定します。
  3. statement を実行します。複数の文を実行するには、ブロック文 ({ ... }) を使用して文をグループ化してください。
  4. 更新式 incrementExpression を、あれば実行します。そして制御をステップ 2 に戻します。


次の関数には、スクローリングリスト (複数選択できる Select オブジェクト) で選択されたオプションの数を数える for 文が含まれています。for 文では変数 i を定義し、それを 0 に初期化しています。iSelect オブジェクトのオプションの個数より小さいかをチェックし、続く if 文を実行し、ループが 1 回りしたら i を 1 だけ増加させます。

<script type="text/javascript">

function howMany(selectObject) {
   var numberSelected = 0;
   for (var i = 0; i < selectObject.options.length; i++) {
      if (selectObject.options[i].selected)
         numberSelected++;
   }
   return numberSelected;
}

</script>
<form name="selectForm">
   <p>
      <strong>Choose some music types, then click the button below:</strong>
      <br/>
      <select name="musicTypes" multiple="multiple">
         <option selected="selected">R&B</option>
         <option>Jazz</option>
         <option>Blues</option>
         <option>New Age</option>
         <option>Classical</option>
         <option>Opera</option>
      </select>
   </p>
   <p>
      <input type="button" value="How many are selected?"
         onclick="alert ('Number of options selected: ' + howMany(document.selectForm.musicTypes))"/>
   </p>
</form>

do...while 文

do...while 文は、指定した条件が false に評価されるまで繰り返します。do...while 文は次のように使用します:

do
   statement
while (condition);

statement は、条件がチェックされる前に一度実行されます。複数の文を実行するには、ブロック文 ({ ... }) を使用して文をグループ化してください。condition が true の場合、その文が再び実行されます。毎回実行された後に、条件がチェックされます。条件が false の場合は実行が停止され、制御が do...while の後に続く文に移ります。


次の例では do ループが最低 1 回は反復され、そして i が 5 より小さい状態ではなくなるまで反復されます。

do {
   i += 1;
   document.write(i);
} while (i < 5);

while 文

while 文は、指定した条件が true に評価される限り文を実行します。while 文は次のように使用します:

while (condition)
   statement

条件が false になるとループ内の statement の実行が停止し、ループの後に続く文に制御が移ります。

ループの statement を実行する前に、条件がテストされます。条件が true を返すと statement が実行され、再び条件がテストされます。条件が false を返す実行が停止され、while の後に続く文に制御が移ります。

複数の文を実行するには、({ ... }) を使用してその文をグループ化してください。

例 1
次の while ループは、n が 3 より小さい限り反復されます:

n = 0;
x = 0;
while (n < 3) {
   n++;
   x += n;
}

それぞれの反復でループは n をインクリメントし、その値を x に加えています。その結果、xn は次の値をとります:

  • 第 1 段階終了後 : n = 1、x = 1
  • 第 2 段階終了後 : n = 2、x = 3
  • 第 3 段階終了後 : n = 3、x = 6

第 3 段階が完了すると条件 n < 3 が true ではなくなるため、ループは終了します。

例 2
無限ループは避けてください。ループの条件が最終的に false になることを確認してください。そうしないとループが終了しなくなります。次の while ループ内の文は永久に実行されます。これは条件が決して false にならないためです:

while (true) {
   alert("Hello, world");
}

label 文

label を使うと、そのプログラムのどこからでも参照できる、識別子を持った文を作ることができます。例えば、ラベルを使用してあるループに名前をつけると、break 文や continue 文を使用して、プログラムがループを脱出するべきかそのまま実行を継続するべきかを示すことができます。

label 文は次のように使用します:

label :
   statement

label の値は、予約語でなければどのような JavaScript の識別子でも使用できます。ラベルを用いて名前をつける statement はどのような文でもかまいません。


この例では、markLoop というラベルを用いて while ループに名前をつけています。

markLoop:
while (theMark == true) {
   doSomething();
}

break 文

break はループや switch 文の終了や、label 文への接続に使用します。

  • break でラベルを使用しないと、もっとも内側にある whiledo-whileforswitch から抜け、続く文に制御を移します。
  • break 文にラベルを使用すると、指定されたラベルのついた文から抜けます。

break 文は次のように使用します:

  1. break;
  2. break label;

1 番目の形式の構文は、もっとも内側のループもしくは switch から抜けます。2 番目の形式の構文は、指定した label 文を持つループなどから抜けます。

例 1:
次の例は、値が theValue である要素のインデックスが見つかるまで、配列の要素について繰り返しを行います:

for (i = 0; i < a.length; i++) {
   if (a[i] == theValue)
      break;
}

例 2: label を用いる break

var x = 0;
var z = 0
labelCancelLoops: while (true) {
    console.log("Outer loops: " + x);
    x += 1;
    z = 1;
    while (true) {
        console.log("Inner loops: " + z);
        z += 1;
        if (z === 10 && x === 10) {
            break labelCancelLoops;
        } else if (z === 10) {
            break;
        }
    }
}

continue 文

continue 文は while 文、do-while 文、for 文、label 文をリスタートさせるために用います。

  • ラベルをつけずに continue を使用した場合、現在繰り返しているものでもっとも内側にある while 文、do-while 文、for 文を終了し、次の反復の実行に移ります。break 文とは異なり、continue はループ全体の実行を終了しません。while ループでは、条件比較部分に戻ります。for ループでは、increment-expression の部分に戻ります。
  • ラベルを用いて continue 文を使用した場合、label で指定されたループ文に戻ります。

continue 文は次のように使用します:

  1. continue;
  2. continue label;

例 1
次の例では、i の値が 3 の時に実行される continue 文を持つ while ループを示します。こうすることで n は順に 1、3、7、12 という値をとります。

i = 0;
n = 0;
while (i < 5) {
   i++;
   if (i == 3)
      continue;
   n += i;
}

例 2
checkiandj というラベルがついた文の中に、checkj というラベルのついた文があります。continue に出くわすと、プログラムは checkj の現在の反復を終了し、次の反復を始めます。continue に出くわすたびに、条件が false になるまで checkj を繰り返します。false が返されると checkiandj 文の残りを完了し、条件が false を返すまで checkiandj を繰り返します。false が返されると、checkiandj に続く文が実行されます。

continuecheckiandj というラベルを持っていると、プログラムは checkiandj 文の最初から処理を続けます。

checkiandj :
   while (i < 4) {
      document.write(i + "<br/>");
      i += 1;
      checkj :
         while (j > 4) {
            document.write(j + "<br/>");
            j -= 1;
            if ((j % 2) == 0)
               continue checkj;
            document.write(j + " is odd.<br/>");
         }
      document.write("i = " + i + "<br/>");
      document.write("j = " + j + "<br/>");
   }

オブジェクト操作文

JavaScript は、オブジェクトの操作に for...infor each...in および with 文を使用します。

for...in 文

for...in 文は、指定した変数をオブジェクトの全プロパティに対して反復します。それぞれのプロパティに対して、JavaScript は指定した文を実行します。for...in 文は次のように使用します:

for (variable in object) {
   statements
}


次の関数は、あるオブジェクトとそのオブジェクトの名前を引数にとります。そして、そのオブジェクトの全プロパティに対して反復処理を行い、プロパティ名とその値をリスト化した文字列を返します。

function dump_props(obj, obj_name) {
   var result = "";
   for (var i in obj) {
      result += obj_name + "." + i + " = " + obj[i] + "<br>";
   }
   result += "<hr>";
   return result;
}

make および model というプロパティを持つ car というオブジェクトでは、次のような結果が得られます:

car.make = Ford
car.model = Mustang

配列
Array の要素に対して反復する方法としてこれを用いることは魅力的かもしれませんが、for...in 文は配列の要素に加えてユーザ定義プロパティに対しても反復処理を行うため、独自のプロパティやメソッドを追加するなど Array オブジェクトに変更を加えると for...in 文は数値のインデックスに加えてユーザ定義プロパティの名前も返します。したがって、配列に対して反復したいときは数値のインデックスを用いた従来の for ループを使用する方がよいでしょう。

for each...in 文

for each...in は、JavaScript 1.6 で導入されたループ文です。for...in に似ていますが、こちらはオブジェクトのプロパティの名前ではなく、プロパティの値に対して反復します。

var sum = 0;
var obj = {prop1: 5, prop2: 13, prop3: 8};
for each (var item in obj) {
  sum += item;
}
print(sum); // 5+13+8 で "26" と出力

コメント

コメントは、スクリプトの挙動を説明するメモに用います。コメントは、インタプリタには無視されます。JavaScript は Java および C++ 形式のコメントをサポートしています:

  • 1 行だけのコメントは、二重のスラッシュ (//) から始まります。
  • 複数行にまたがるコメントは、/* から始まり */ で終わります。


以下に 2 つのコメントの例を示します:

// これは 1 行コメント。

/* これは複数行コメント。どんな長さでもかまわない。
書きたいことをなんでもここに書ける。*/

例外処理文

throw 文を使用すると例外を投げることができます。また、try...catch 文を使用すると例外を処理することができます。

try...catch 文を使用して Java の例外を処理することもできます (これには バグ 391642 の問題がありますが)。この情報についてはJavaScript での Java の例外の処理およびJava と JavaScript との通信をご覧ください。

例外の種類

JavaScript では、ほぼどのようなオブジェクトでも投げることができます。とはいえ、必ずしも投げられたオブジェクトすべてが同等に作られているわけではありません。数値や文字列をエラーとして投げる方法はよく用いられますが、この用途のため特別に作られている例外の種類のいずれかを使用する方がより効率的である場合がよくあります:

throw 文

throw 文は、例外を投げるために使用します。例外を投げるときは、投げたい値を含む式を指定してください:

throw expression;

特定の型の式だけではなく、あらゆる式を投げることができます。下記のコードでは、さまざまな型の例外を投げています:

throw "Error2";
throw 42;
throw true;
throw {toString: function() { return "I'm an object!"; } };
注意: 例外を投げる際に、オブジェクトを指定できます。すると、catch ブロックでそのオブジェクトのプロパティを参照できます。次の例では、UserException という種類の myUserException オブジェクトを作成します。
// UserException という種類のオブジェクトを作成
function UserException (message){
  this.message=message;
  this.name="UserException";
}

// 文字列として使用されるとき (例: エラーコンソール上) に
// 例外を整形する
UserException.prototype.toString = function (){
  return this.name + ': "' + this.message + '"';
}

// UserException のインスタンスを作成し、それを投げる
throw new UserException("Value too high");

try...catch 文

try...catch 文はテストしたい文のブロックを指定し、さらに投げられるであろう例外に対する 1 つ以上の対処方法を指定します。例外が投げられると、try...catch 文がそれを受け取ります。

try...catch 文は 1 つの try ブロックと 0 個以上の catch ブロックで構成されます。前者は 1 つ以上の文を含みます。後者は try ブロックで例外が投げられた場合にどうするかを指定する文を含みます。すなわち、成功させたい try ブロックと、失敗した場合に制御を移す catch ブロックで構成されます。try ブロック内 (もしくは try ブロック内から呼び出された関数内) のいずれかの文が例外を投げると、制御はすぐに catch ブロックに移ります。try ブロックで例外が投げられなかった場合は、catch ブロックは飛ばされます。finally ブロックは try および catch ブロックを実行した後に実行します。ただし try...catch 文の後に続く文より先に実行されます。

次の例では try...catch 文を使用しています。この例では渡された値に基づいて、配列から月の名前を取り出す関数を実行します。値に対応する月の数字 (1-12) が無い場合は "InvalidMonthNo" という値を持つ例外が投げられ、catch ブロックの中の文は monthName という変数に unknown という値をセットします。

function getMonthName (mo) {
    mo=mo-1; // 月の数字を配列のインデックスに合わせる (1=Jan, 12=Dec)
    var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul",
          "Aug","Sep","Oct","Nov","Dec");
    if (months[mo] != null) {
       return months[mo]
    } else {
       throw "InvalidMonthNo"
    }
}

try {
// 実行を試みる文
    monthName=getMonthName(myMonth) // 関数は例外を投げることがある
}
catch (e) {
    monthName="unknown"
    logMyErrors(e) // 例外オブジェクトをエラーハンドラに渡す
}

catch ブロック

単一の catch ブロックを用いると、try ブロックで生じうるすべての例外を扱うことができます。

catch (catchID) {
  statements
}

catch ブロックは、throw 文で指定された値を保持する識別子 (上記の構文における catchID) を指定します。この識別子を使用して、投げられた例外についての情報を得ることができます。JavaScript は catch ブロックに入るときにこの識別子を作成します。識別子は catch ブロックにいる間だけ持続します。つまり、catch ブロックの実行が終わると、その識別子はもう使えなくなります。

例えば、次のコードは例外を投げます。例外が生じると、制御が catch ブロックに移ります。

try {
   throw "myException" // 例外を生成
}
catch (e) {
// どのような例外も扱う文
   logMyErrors(e) // 例外オブジェクトをエラーハンドラに渡す
}

finally ブロック

finally ブロックは、try および catch ブロックの実行が終わった後に実行される文で構成されます。ただし、try...catch 文の後に続く文より先に実行されます。finally は例外が投げられても投げられなくても実行されます。例外が投げられた場合、finally ブロック内の文はたとえ例外処理をする catch ブロックがなくても実行されます。

finally ブロックを使用することで、例外発生時に適切にスクリプトを停止させることができます。例えば、スクリプトで使用していたリソースを解放する必要があるかもしれません。次の例ではファイルを開き、そのファイルを使用する文を実行します (サーバサイド JavaScript ではファイルにアクセスできます)。ファイルを開いている間に例外が投げられると、スクリプトが停止する直前に finally ブロックがそのファイルを閉じます。

openMyFile();
try {
    writeMyFile(theData); // エラーを投げる可能性がある
}catch(e){
    handleError(e); // エラーを受け取り、それを処理する
}finally {
    closeMyFile(); // 常にリソースを閉じる
}

finally ブロックが値を返す場合、その値は try および catch ブロックの return 文にかかわらず、try-catch-finally 全体が生成する戻り値になります:

function f() {
    try {
        alert(0);
        throw "bogus";
    } catch(e) {
        alert(1);
        return true; // この戻り値は、finally ブロックが完了するまで保留されます
        alert(2); // ここには到達できません
    } finally {
        alert(3);
        return false; // 前の "return" を上書きします
        alert(4); // ここには到達できません
    }
    // ここで "return false" が実行されます
    
    alert(5); // ここには到達できません
}
f(); // 0, 1, 3 とアラート表示し、false を返します

try...catch 文のネスト

1 つ以上 try...catch 文を入れ子にすることができます。内側の try...catch 文に catch ブロックがない場合、囲んでいる try...catch 文の catch ブロックがマッチしているかが確認されます。

Error オブジェクトの活用

エラーの種類に応じてより洗練されたメッセージを得るために、'name' および 'message' プロパティを用いることができます。'name' はエラーの一般的なクラス (例えば 'DOMException' や 'Error') を示し、一方 'message' は通常、Error オブジェクトを文字列に変換して得られるものより簡潔なメッセージを示します。

独自の例外を投げる場合はこれらのプロパティを利用するために (catch ブロックで独自の例外とシステムの例外を区別しない場合など)、Error コンストラクタを用いることができます。例えば:

function doSomethingErrorProne () {
   if (ourCodeMakesAMistake()) {
      throw (new Error('The message'));
   }
   else {
      doSomethingToGetAJavascriptError();
   }
}
....
try {
   doSomethingErrorProne();
}
catch (e) {
   alert(e.name);// 'Error' とアラート表示
   alert(e.message); // 'The message' または JavaScript のエラーメッセージをアラート表示
}

ドキュメントのタグと貢献者

最終更新者: ethertank,