マウスコンピューター/G-Tune

2008.02.07 改



ステートメント
ここまでで、ステートメントを実行文や命令文と言う言い方をしてきました。 既に出ているのが、定義用ステートメント var や function です。 また、解説中に if(条件){ ステートメント; } なども多く出ています。 このページでは、if文の様にプログラムの流れを制御する為に用意されている ステートメントに付いて解説して行きます。

最低限必要な 制御用ステートメントは if文です。 if文さえ理解できていれば、他の制御文を if で代用させてしまう事も可能ですので とにかく、if文を完全に使いこなせるように頑張ってください。 もう一つ覚えておくと便利なのが、for()文で if文+再帰法 での代用も可能ですが for()文は if文に次いで使用頻度が高いと思います。
残りは明らかにそれを使う方が便利な場合もありますし、覚えておく方が当然 プログラムの流れを考え出す幅が広がります。
解説は if文、for()文に重点を置きます。残りは自分でテストを繰り返してください。


if 〜 else 〜

top
◆if文とは 英語そのままで『 もし〜 なら 』 と言う意味です。
if文には if〜if〜 else〜 があります。必要に応じて else{ } を付けます
if(条件){ 成立後ステートメント; }
もし 条件が成立すればステートメントを実行します。成立した場合のみの条件
if(条件){ 成立後ステートメント;}else{ 不成立後ステートメント;}
条件が成立した場合と、不成立の場合にそれぞれステートメントを用意しています。
つまりif文は 条件成立した場合のみ実行 や、成立すれば〜 不成立なら〜 の様に 特定の条件に対して条件分岐する為の物です。

◆条件
if()文は ifの後ろに 必ず括弧()をつけます。if文はその括弧の中の条件が満たされるかどうかを判断します。 条件が満たされいるかどうか? と言う事ですので 基本的にはこの括弧内に対しての 真偽(true or false)評価となります。
// 式の評価
if( $x >= 10){    }  // $x が10以上なら成立

// 真偽変数
$navi = ( navigator.userAgent.indexOf('msie')>=0 );
if($navi){   }  // $navi がtrue(真)なら成立
if(!$navi){   } // !$naviがtrue つまり $naviがfalseなら成立

// 真偽関数
if( docheck() ){   } // docheck()関数からの戻り値が trueなら成立

//複数条件  and
if( $navi && $x >= 10){  } // 2つの条件が両方とも成立すれば成立
if( !$navi && $x >= 10){  } // 2つの条件が両方とも成立すれば成立
(2つ目は $naviがfalse で $xが 10以上なら)

//複数条件  or
if( $navi || $x >= 10){  } // 2つの条件の片方でも成立すれば成立
この様に、括弧() 内に入る式によって様々な条件を付けられます。 演算子によって逆の意味にもなりますので注意してください。 例えば !$navi の例ですが、通常if($navi){ }else{ }を使う場合 if($navi){ statementA; }else{ statementB; } となりますが $naviが false の場合だけに 実行したい場合等があります。この様な時には !$navi として論理否定した値が成立すれば〜 と書く事で成立するわけです。
また、条件の考え方として基本は false 時々 true の様な場合には その流れを文章としての意味合いをわかりやすくする為に
if($navi){ statementA;}else{ statementB; }ではなく
if( !$navi){ statementB; }else{ statementA; } と書く事もあります。
この2つは全く同じ事ですが、文書的には 『もし 〜 でなければ』となりますね。
この論理否定の時に間違え易いのですが、論理否定 ! を使う場合に 『 条件が成立しなければ 』と言う意味ではありません、『 〜では無い と言う条件が成立すれば』と言う日本語になります。 ifは常にその括弧()内の式が否定形であれ肯定形であれ、式が成立した(真の)場合にのみ 成立 と判断します。

◆中括弧 { }
この括弧は if文特有の物ではありません。{ } は ある複数の処理をまとめて、1つのグループとする時に使う物です if文の場合には if文に続くステートメントが 1つのみの場合には この 中括弧{ } を省く事ができます。
if($x < 0) alert('マイナスです');

if($x < 0)
alert('マイナスです');
$xが 0 未満の場合には アラートが出ます。 この場合、if条件成立によって実行されるステートメントが 1つなので、中括弧は使っていません。
if($x < 0) alert('マイナスです');alert('ok?');

if($x < 0)
alert('マイナスです');
alert('ok?');
この場合はどうなるでしょう? javascriptは if文に続く、1つのステートメントのみを if条件成立によるステートメントと解釈します。 従って、alert('ok?') は if条件に関係なく実行されます。

この様に 中括弧 {} は ステートメントを1行に書く複数行に分けるなどの関係なく 2つ以上(複数)のステートメントがある場合には必ず必要になります。
if($x < 0){ alert('マイナスです');alert('ok?'); }

if($x < 0)
{
alert('マイナスです');
alert('ok?');
}
これなら alert('マイナスです'); も alert('ok?'); も if条件が成立した場合にのみ実行されます。
これらの事は else を使う場合にも適用できます。
if($x < 0) alert('負の数です');
else alert('正の数です');

if($x < 0)
alert('マイナスです');
else
alert('ok?');
ここでは、ifに対しても else に対しても 1つのステートメントがついています。 先ほど書いたように1ステートメントなので 中括弧は使っていません。 どちらか、または両方に複数のステートメントが必要な場合は、その複数のステートメントのある方にだけ 中括弧を付ければ済みます。
if($x < 0){ alert('負の数です');
alert('リセットを押してください');
}
else alert('正の数です');

私の場合は、1ステートメント の場合も必ず中括弧を付けています。 これは、括弧によってブロック化されて見易くなるのと、ステートメントの追加や、削除の時に 一々気にしないで済むように。単純なミスで泣かない様にする為です。
また最近のオブジェクト型の書き方(オブジェクトの中に関数など全てを入れ込む)をする場合にも、 1行表示でもエラーにならない方法としても便利なので。 if(){ } 又は、if(){ }else{ } と言う決り型として使っています。

◆if文 複数分岐
if文は 2つ以上組み合わせて使ったり、その条件を複雑にする事で 様々な分岐を作り出す事ができます。自分のプログラムの目的に添って if文を構成する事が必要になってきます。
次の例は if文の 成立・不成立の場合に、その後でもう一度分岐させます。
if(条件a){
    statement1;
    if(条件b){
        statement2;
    }else{ statement3; }
}else{
    if(条件c){
        statement4;
    }else{
        statement5;
    }
}
ここでは 条件aが整った場合、整わなかった場合に それぞれ 条件b、条件c と また分岐されています。この様にする事で、条件を絞り込んで行く事ができます。
if($navi && $x = 10){
    statement1;
}else{
    if($navi){ statement2; }
    if($x = 10){ statement3; }
}
この場合は 2条件 両方成立すれば statement1を実行します。 両方が満たされない場合には else に行くわけですが 片方だけ満たされている場合もありますね? その場合こんな感じで、 else内で 単独成立条件を書きます。

if文は その条件に使う演算子や、複数のif文の組み合わせにより サンプルにするには多すぎるほどの様々な条件分岐ができます。 後はプログラミングする時に考えてみてください。 気を付けなければいけないのが、条件を絞り込んだり複雑にしていくと どの条件にも当てはまらないような、ブラックホールができてしまう事があります。 予期せぬデータの受け渡しによって、そのブラックホールに落ち込むと そこで処理が止まってしまったりしますので注意してください。 常に、『〜なら』だけでなく『それ以外は?』を考えて行きます。

◆並列条件
if文は分岐でもありますが、条件を満たせば実行するという単純な実行としても使いますね。 特に elseを使わない場合は条件に合えば 〜 する。という感じになります。
var $color;
if($x = 10){ $color = "red"; }
if($x >= 10){ $color = "yellow"; }
if($x < 10){ $color = "green"; }
if($x > 0) { $color = "blue"; }
この様に if文をならべて条件が満たされた物だけ実行させる事ができます。 しかし、この様な場合には 条件さえあえば複数の if文が実行される可能性がありますので 条件の付け方に気を付けねばなりません。故意に複数実行させたい場合は構いませんが。 この例では $x が 10 の場合は、$colorは red になり、yellowになり、blueになります。 最終的な $colorの値は最後に実行された blue になります。 何らかの目的でわざとこうしているなら良いのですが、もっと微妙な条件付けで 測らぬ動きをしてしまう場合もありますので注意してください。 並列の場合の複数実行を回避するには、常に else をつけて、『 〜 でない場合は 』の中に 次の条件を記述して行く事になります。
var $color;
if($x = 10){ $color = "red"; }
else{  if($x >= 10){ $color = "yellow"; }
       else{ if($x < 10){ $color = "green"; }
             else{ if($x > 0) { $color = "blue"; } }
        }
}
これで$xの条件が当てはまった時点で実行される$color= "";は1つになります。
perl言語などでは elsif() と言うものがありますが、javascriptにはありませんので elsif()『それ以外でもし〜なら』を表現したい場合は、else{ } の中に if文を書くという形になります。

◆条件演算子
if文は 条件演算子 a? b:c を使って表現できる場合があります。 条件演算子は演算子ですから、式の中にif文を埋め込むと言う事ができると言う事にもなります。
a? b:cは『 aが真ならbを、偽ならcを』という意味です。詳細は演算子のページを。
// $nameは名前を、$sexは性別を受け取っている変数とし
// $sexには必ず maleかfemaleが代入されているとします

if($sex == 'male'){ $name += "くん"; }
else{ $name += "さん";  }

//条件演算子で書くと
$name += ($sex == 'male')? "くん": "さん";
ここでは $nameで受け取った名前に 男なら『くん』女なら『さん』を追加結合しています。 この様に 真なら偽なら と言う2択条件のものであれば、条件演算子に置換えて使えます。 ここでは余り有効に見えないかもしれませんが
$mes = $name + (($sex == 'male')? "くん": "さん") + (($hour > 18)? "こんばんは": "こんにちは");
の様に 1つの式の中で使えるので状況によっては if文よりも使い勝手が良いです。 この条件演算子は優先順位が低いので 状況に応じて括弧()で囲んであげます。

if文の説明が長くなりましたがこれで終わります。 今後も、各ステートメントの代用として時折でてきます。


switch

top
netscape4/internetexplorer4 以上にのみ有効
switch は if文と同じように 条件によって実行するステートメントを変える事ができる 条件分岐型のステートメントです。
同じ条件型のif文では 条件が成立(真)なら実行、不成立(偽)なら実行しない、またはelseブロックを実行します。 つまり、基本的に2択になるわけです。 しかし switchステートメントは評価する条件の結果に応じて、何通りでも 実行ブロックを設定する事ができます。 if文で言うと、式の結果を得てその結果に対して if文をいくつも並列で並べたような状態になります。
switch (条件) {
   case ラベル1:
      statementa;
   case ラベル2:
      statementb;
   case ラベル3:
      statementc;
   case ラベル4:
      statementd;

   default:
      statemente;
}
switchでは 条件 を評価してその値と同じラベルがあれば そのラベル以降に書かれている全てのステートメントをを実行します。 default: というブロックは、 条件に関係なく実行されます。 通常どのラベルとも合致しなかった場合などの為にあります。 従って、通常 左の様な書き方の場合は、条件に合致するラベルがあればそのラベルより下に書かれている ステートメントを全て実行します。 つまり、スタート地点の決定をラベルとの合致で得る事になります。 例えば ラベル3 と条件が合致するとc,d,eのステートメントが実行されます。

これでは、なんだか制御しきれていない様に思えます。あまり役に立たないようにも。
しかし switchステートメントでは breakステートメントを使用できます。 breakステートメントがあるとその場でswitchステートメント処理が終了します。
switch (条件) {
   case ラベル1:
      statementa;
      break;
   case ラベル2:
      statementb;
      break;
   case ラベル3:
      statementc;
      break;

   default:
      statementd;
}
これが一般的な switchの使い方です。
条件と合致するラベルがあると、そのラベルブロックから実行を始め breakステートメントが見つかるまでの間にある処理を全て行います。 breakが見るかると終了しますので defaultも実行されません。 条件と合致するラベルが無い場合のみ、default:ブロックが実行されます。
defaultブロックは、必要な場合のみ作ればよく、不要な場合は記述する必要はありません。 defaultが無い場合で合致するラベルが無い場合は、そのまま何も行われずに終了します。

この様にswitch では 条件に対するラベルを作り、全てのラベルブロックの最後にbreakを記述する事で if文を並べたような構造になります。しかも、breakがあるので複数の条件が行われる事も無く if文で制御するような複雑な何重構造にならずに済みます。

◆case の書き方
case の後ろに半角を開けて、ラベルを書きます。ラベルは変数であったり、数値であったり、true、falseの様な 真偽であったり、文字列である場合もあります。文字列の場合はかならずシングルorダブルクォーテーションで囲ってください。 ラベルの後ろには コロン( : ) を付けます。 ステートメントは行を変えなくても構いませんが見やすい形で整理してください。 1ラベルブロックにステートメントが複数になる場合も 中括弧{ }で囲む必要はありません。
switch ($name) {
   case "artemis": // 文字列ラベル
      statement;
      statement;
      break;
   case true:  // 真偽などの特殊な値
      statement;
      break;
   case $member: // 変数ラベル
      statement;
      break;
   case 2: //数値ラベル
      statement;
      break;
   case 4:
   case 5:
      statementD;
      break;

   default:
      statement
}
このいい加減な例は $name と言う変数の値と合致するラベルを探しているわけですが ラベルをとりあえず4種の方法+αで作ってみました。 この様に、ラベルは比較参照できる対象であればokです。
case 4、case 5は ラベルの部分で or などが書けない為、並列で書いて どっちの条件もstatementDを実行する事になります。

真偽判定での条件分岐などは if文で十分でしょうが 真偽以外の複数の結果が予測できる式の結果によって分岐させたりする場合等 if文よりも構造的にも簡潔に整然と書けますので使って見てください。

breakを使わないとラベルは『始点』になるだけなので注意してください。


for

top
for文は繰り返し(ループ)を行う為のステートメントです。
ループとは、ある一定の条件が満たされるまで処理を繰り返す事をいいます。 ループを作る時は、このある一定の条件をきちんと定義しなければなりません。 この定義が間違っているといつまで経っても終わらないループ=無限ループとなり システムがフリーズしたりしますので気を付けてください。

◆for文の構造を書きますが、文字で書くと難しく感じるかもしれません。
for( カウンタ変数設定; 条件評価; カウンタ更新 ){
   繰り返しを行うステートメント
}

となります。
カウンタ変数設定、条件評価、カウンタ更新 は セミコロン(;)で区切ります。

◆さて、これでは良くわからないでしょうから、例を見ながらの説明には要ります。
for( i=0; i<10; i++ ){
    alert(i);
}
まずfor文の繰り返しの順序を説明します。
1.最初に i=0; と言う カウンタ変数の設定式を行います。今 i は 0 です。
ここは、初めてfor文に入った時のみ実行されます。カウンタ変数はローカルです。
2.次に for文の実行条件を評価します。 i<10; なので 条件はパスします。
3.条件が通ると alert(i) を実行します。ここに書かれるステートメントの実行
4.カウンタ更新を行います。i++; でインクリメントしています。
この時点で i は 1 になっています。次に2回目に入ります。
6.条件評価をして 通れば2回目のステートメントを実行します。
for文はこの様な順序で繰り返しを行い、条件評価が 偽になると拒否されて for文の次の別の処理へ移ります。
何と無くわかったでしょうか?
for文で、毎回変化して行くのはカウンタ変数の i です。 i は 回数を数える為だけに使われても構いませんし、 この毎回変化する i を ステートメントの方で利用する事も一般的です。
for( i=1; i<7; i++ ){
    document.write( "<font size=" + i + ">あ</font>")
}

font sizeを1から6まで変化させて文字打出しをしています。
for(i=6; i>0; i--){
    document.write( "<font size=" + i + ">あ</font>")
}

font sizeを6から1まで変化させて文字打出しをしています。
----------------------------------------------------------
$num1 = $num2 = 10;
for( i=2; i<=10; i++){
	$num1 *= $num2;
}
alert($num1);
$num1は毎回処理後の値が入ります。$num2は 10のままです。
これは $num1=$num2=○○の○○に設定した値の10乗を求めています。
ここでは i をステートメントに使っていません。
----------------------------------------------------------
他によく使うのが配列要素設定などです
var $img = new Array(10);
for(i=0; i<10; i++){       // 配列は インデックスが0から
    $img[i] = new image(); //各要素を画像オブジェクトに
	$img[i].src = "./img" + i + ".gif"; //srcプロパティを設定
}
この場合 img0.gif〜img9.gif までの画像を
$img[0] 〜 $img[9] の srcプロパティに入れて読み込んでいます。
配列の番号と 画像の番号を揃えるのがコツです。
画像名がそれぞれ違うと for文ではできません。
画像名の数字部分が 1ずれているなら
$img[i].src = "./img" + (i+1) + ".gif"; とすれば良いでしょう。
この様にfor()にはカウンタ更新と条件評価がありますので簡単に繰り返しができます。
中括弧 { }に付いてですが これは、if文と同じく ステートメントが1つの場合は省けます。 2つ以上のステートメントを書き込む時は必ず中括弧でグループ化します。

サンプルでは、カウンタ変数初期値や条件評価、等で実数値ばかり使っていますが 変数を使う事も可能です、その為カウンタの初期値や、ループの最終条件等を 状況に応じて自由に変更した上でループする事ができます。
for(i=$begin; i<$end; i*$n){
    ステートメント;
}
このループに入るより前に、きちんと $begin、$end、$n等の変数の値が設定されていれば 問題なく forループが実行されます。 よく使われるのが $ary.length($aryは配列)です。
for(i=0; i<$ary.length; i++)やfor(i=0; i<=$ary.length-1; i++) などです。 配列と言うのは lengthプロパティで取り出せる値の数だけ配列要素を持っています。 配列の初期index番号は 0 になりますので上限は length より1 小さいindex番号となります。 その為 i<$ary.length や i<=$ary.length-1 と言う上限の書き方になります。

例えば番号を二つ選んでもらって、その2つの数値の間だけを処理する場合
$a と $b にユーザーが選んだ数字が入ってるとします。どちらが大きいかわかりません。 こういう場合は、2つを比較して小さい方を取り出してくれるMath.min、逆に大きい方を取り出してくれるMath.maxを利用します。
for(i=Math.in($a, $b); i<Math.max($a, $b); i++)
とすれば、小さい方から大きい方に順次処理ができます。

◆カウンタ更新 部分
カウンタ更新部分は先ほどからインクリメントやデクリメントのサンプルだけですが ここは、必要に応じたを1つ入れられます。
for(i=0; i<=100; i+2){ } // iは2ずつ増える、偶数になる
の様にもできます。

また、この部分は通常指定できる式は1つですが カンマ演算子を使う事で、複数の式を入れる事も可能です。
var j=0;
for(i=1; i<10; i++,j++){
    alert(i+j);
}
ここでは、i++ と j++ の2つの式を行っています。 実際この例では、ここにわざわざ書く必要がありませんけど・・・ 次も同じ意味になりますので。
var j=0;
for(i=1; i<10; i++){
    j++;
    alert(i+j);
}
一応できると言う事を知っておいてください。
ちなみに次のようにした場合、i は インクリメントされてから、k に足されています。

var j=0;
for(i=1; i<10; i++,k+=i){
    alert(i*k);
}
カンマ演算子を使って複数の式を指定する事も可能だ、と言う話でした。

◆for文を途中で中断させる
breakステートメントは for文でも使用可能です。
breakステートメントは、主にswitchとループ文の中で使われます。
for文で処理している途中で、何らかの目的が果たせたら、つまり条件が整えば breakするようにしておけば、カウンタが条件評価ではじかれるより前に途中で forループ処理を抜け出す事ができます。
for(i=1000; i>0; i--){
    window.status = i;
    if(i%100 == 0){ if(!confirm('続けますか?')){ break; } }
}
この例ではブラウザのステータスバーに 1000〜1まで数字を連続カウントダウンします。 ただし、途中で 100で割って余りが無い時、つまり 1000、900、800、700・・・ と言う100の倍数の目の時に confirmボックス(はい、いいえを受け付けるもの)を表示します。 『はい』を押すとそのまま続けられますが、『いいえ』を押すと breakにより、処理が中断します。 書き写してテストしてみてください。

◆if文で同じ事をする
if文で同じ事ができます。この場合 関数と再帰法を使います。
$i=1;
function doroop(){
    if($i<7){
    document.write( "<font size=" + i + ">あ</font>");
    $i++;
    doroop();
    }
}
これは for文と同じ順序になるようにif文で作りました。
まず、関数より前に $i="1" を行います。 評価が通れば、ステートメント実行、インクリメントをして 自分自身をまた呼び出します。ただこの例では、最後に呼び出された時に 条件ではじかれるので、一回呼出しが無駄ですね。次のようにするのが楽です。
$i="1";
function doroop(){
    document.write( "<font size=" + i + ">あ</font>");
    $i++;
    if($i<6){ doroop'(); }
}
自分自身の呼出しの部分のみをif条件にすれば良いでしょう。

さて、ココまでの例では
for(i=0; i<100; i++ ){ }
の様にしていますが、実はこの状態だと変数 i はグローバル変数です。
『グローバルにする必要がある』という時以外は、ローカルにして使う方が使い捨て変数として便利です。
for(var i=0; i<100; i++ ){ }
これで、ある関数の中でこのfor文を使えば、iはその関数だけで通用するローカル変数となります。

あと、前の方に書きましたがこの i の部分の変数は、for文の中で利用される事が多いです。 この i は 数値型の変数です。 文字列として扱いたいケースもあるので、数値型である事は意識して置いて下さい。


for 〜 in

top
for( 変数 in オブジェクト){ }は初心者には使用頻度の高いループではないかもしれません。 オブジェクト、連想配列で使用するのが基本なので、初心者には少し理解しにくい説明になると思います。

◆まず簡単な説明から
オブジェクトにはそのオブジェクトに属するプロパティとメソッドがある事は説明してきました。 for( ローカル変数 in オブジェクト){ } を使うと、forが勝手にループを繰り返して このオブジェクトのプロパティ名を1つずつ全て取り出す事ができます。 プロパティのリストが無くなるとループを勝手に抜けます。 ローカル変数には for文でループして 毎回順番に取り出す、プロパティが一時的に格納されます。 また、連想配列というものも、キー(名前)がその連想配列のプロパティであり、プロパティが持つ値があります。
とりあえず、例を出します。
for(i in navigator){
    document.write(i + "<br>")
}
これを実行すると、navigatorオブジェクトに属するプロパティ名の一覧が表示されます。 また取り出した名前を利用して、そのプロパティの現在の値を読み取るには 次のようにして、プロパティを参照します。
for(i in navigator){
    document.write(navigator[i] + "<br>");
}
この2つを組み合わせて、プロパティ名とその値を表にしてみます。
document.write("<table border>");
for(i in navigator){
    document.write("<tr><td>" + i );
    document.write("</td><td>" + navigator[i] + "</td></tr>");
}
document.write("</table>");
これを書き移して実行してみてください。あなたの使用中のブラウザの navigatorオブジェクトのプロパティと その値がテーブルリストになっていると思います。
この様にfor(変数 in オブジェクト){ } ではオブジェクトのプロパティ名をあるぶんだけ全部取り出すのです。 for(変数 in オブジェクト)での この後ろの中括弧 { } は ステートメントが1つのみなら省いて構いません。

◆ここから先の for〜in については、配列と密接な関係があるので配列の部分でもお話する事を重複して ここでも解説しておきます。

◆なぜ 配列でもないのにnavigator[i]と言う配列扱いをして値が取れるのか?
javascriptではオブジェクトは配列とほとんど同じものだと思ってください。 オブジェクトとは、実は そのプロパティを要素に持つ配列の形になっています。 ただ、普通の配列と違うのは、配列の並び順、つまりindex番号が無い事と、その配列の長さ(要素数)を とりだすlengthプロパティを使えない事です。
先ほどのfor 〜 in ではnavigator[i] での i は 毎回取り出すプロパティ名だと書いたはずです。 つまり、これはnavigator["プロパティ名"]を言う形で、その要素を取り出しています。 javascriptの配列にはインデックス番号の他に、連想処理と言う方法があります。 オブジェクトは基本的にこの連想処理配列になっています。逆に言えば 連想処理配列を自分で作るとオブジェクトを作るのとほぼ同じ事になります。
(ほんとうは連想配列(Array)とオブジェクトは形は似てても微妙に違います)

連想処理のベースとなるユーザー定義オブジェクト生成については省きますが、
ごく簡単にできる、次の様な連想処理配列を作る方法があります。
$list = new Array(); //配列オブジェクトの生成
$list["green"] = "みどり";
$list["red"] = "あか";
$list["blue"] = "あお";
$list["yellow"] = "きいろ";
これで、$listは配列でありオブジェクトであります、配列メンバー名を使ってその値を取り出せます。 ただし、インデックス番号での取り出しはできません。 配列としてのオブジェクトの場合はドットによるオブジェクトのプロパティとしても取り出せます。
alert( $list[0] );  //  undefined になります
alert( $list["green"] ); // 『みどり』 と表示されます
alert( $list.green);  //『みどり』 と表示されます
alert($list.length); // 0と表示されます
オブジェクトは、この様な連想処理としての配列メンバ名を持っています。 従って、 for〜in で名前を取り出してそれを配列メンバ名として指定する事でその値を取り出せるのです。

◆なぜ連想処理の説明までしたのか?
javascriptでのオブジェクトが配列であると言う事を踏まえて考えると for〜in は 実はオブジェクトに対してではなく、配列に対して使える物であると言う事になります。
for(変数 in オブジェクト)for(変数 in 配列) と同じ事になります。
ただし このfor〜inで取り出すのは配列メンバ名になります。 従って、普通の indexを持つ配列でこれを行うと、インデックス番号だけが取り出されます。
$member と言う普通の配列があり 10個の要素を持っているとします
for(i in $member){
    document.write(i);
}
これだと、ただ 0〜9 の数字が表示されるだけです。要素を知りたければ
    document.write($member[i]);
こう書く事になります。しかし、i は 0〜9 つまり連続したindex番号です
わざわざ名前で取り出す必要もなく
for(i=0; i<$member.length; i++){  //$member.lengthは配列の長さ
	document.write($member[i]);
}
これで十分なはずです。
逆に連想処理配列では、index番号が無いので普通のfor文では、そのメンバ名がわからなければ 要素を取り出しようが無いと言う事になります。
その為に for(変数 in 配列){ } があるのです。
と、私は解釈しています。実は独断です(^^;)。
難しい定義は置いておいて、先ほどやってみてくださいと書いた
document.write("<table border>");
for(i in navigator){
document.write("<tr><td>" + i );
document.write("</td><td>" + navigator[i] + "</td></tr>");
}
document.write("</table>");

この 緑の部分を、javascript上に存在するオブジェクト名にする事で そのプロパティの名前と、現在の値を得る事ができます。(一部不可?) document以下のオブジェクトに付いては、複数になるので、1つを特定しなければできません。
document.images // これは画像の数のプロパティのみ
document.images[0] // 1つめの画像
画像のプロパティを知りたいなら imgタグを1つ作り document.imges[0] と言うオブジェクトを指定してfor〜in を行います。

◆break
for〜in でも breakが使えます。特に例は出しませんが 何らかの条件が揃った時点で breakさせるようにすれば良いだけです。 breakステートメントが実行された時点で for〜inループから抜ける事ができます。

全く別の所に書いてありますが、普通配列にfor(変数 in 配列){ }を使うと微妙に違う結果が出ることがあります。 普通配列には必ずindexで取り出す方法を使うようにしてください。

普通のfor文の所でも書きましたが、
for(key in array){ }の様に書くと key はグローバル変数となります。
従って使い捨ての変数として for(var key in array){ } と書く事の方が多いです。

あと、この key は 文字列型になります。


while

top
whileループは forループと似ていて、forループの変わりに使う事も簡単にできます。 この whileループの特徴は 条件評価のみが構文上必須項目になっている点です。 つまり、カウンタの初期定義とカウンタ更新が用意されていません。 自分で用意する事になります。 従って、カウンタと言う数値的な方法でループを終了をさせるのか、あるいは 状況と言うキーワードでループを終了させるのかが自由になります。 forループではカウンタ更新という形が用意されているのでどうしても数値的な条件でのループ制限に偏ってしまいます。 先ほど書いたようにwhileループにはカウンタ更新と言う手段が必須になっていないので 明確に終了させる設定をしないと、無限ループにはまりやすいのでテストする時も気を付けて 作って行かねばなりません。

◆while 基本構文
while(条件評価){
   ステートメント;
}

条件評価が 真(true)の間はステートメント何度も繰り返して実行します。
ご覧の通り 条件評価に使われる条件を更新する場所が決められていません。 自分で設定する事になります。まず基本的な数値での制御をしてみましょう。
var i=0;
while(i<100){
    window.status = i;
    i++;
}
まず、カウンタとして使う変数を、whileループ外で初期値設定します。 whileループでは、iが 100未満なら何度も ステートメントを実行します。 iがきちんと更新されねば終わらないので、i++ でインクリメントして 一回毎に1ずつ増やしています。従ってこのループは iが100になって終わりますので、0〜99 までの100回繰り返されます。
大事な事は、初期値設定を whileループ外で行う事です。 whileループ内で i=0; の様な記述があると、毎回実行されますので iは 0,1 の繰り返しになり永遠にループが続きます。
この様に、数値でのカウンタを使うのであれば forループと全く同じ使い方ですね。
もっとwhileらしいサンプルを書きたいのですが、思い付く物がみな 数値に関する制御になってしまいますがもう一つサンプルを。
var n=45; //引かれる数
var i=4; //引く数
var y=0; //ループ回数を変数に

while(n>=i){
n = n - i;
y++;
}
document.write("商"+y);
document.write("余り"+n);
割り算の商と余を引算でやっています。

nをiで引ける間 ループをします。 引けなくなったら n には 余りが残ります。 繰り返す事ができた回数が 商 になります。

ここでは nとiを固定していますが フォームで受け取って関数へ、、、という形で汎用な割り算のプログラムができます。 (これはマイナスの処理が無いので正の数のみですが)
whileはこの様に回数ではなく、状況を条件にできるわけです。

for文のカウンタ更新では基本的に書き込める式は1つです、カンマ演算子を使って2つ以上書けますが 式として成り立つ単純な物だけです。if文などの条件制御を使えません。whileでは カウンタ更新をステートメントとして、実行ブロックに書き込みますから 様々な条件付けなどが自由にできるわけです。
while(条件) は 条件が真の間繰り返されますから、この条件を ブール型変数(真と偽の値を持つ変数)にして 何らかの条件が整えばこの変数を 偽(false)にすれば、止める事も可能です。 forループを使うか、whileループを使うかはその時々で適している方を判断するしかないでしょう。

◆中括弧 { } は ステートメントが1つであれば省く事ができます。
◆breakステートメントが使えます。while(条件)の条件以外でループを抜けたい時は if文などで条件を付けた breakステートメントを入れ込みます。

losseon1として スロットマシーンの作り方を解説していますが スロットのドラムが回転する部分を for、やwhileループにしていない理由があります。 stopボタンが押されるまでループを続けるのですから、whileなどが適しているように見えますが whileループの繰返し速度は、システムの許す限りの速さで繰り返され、かなり速いです。 この速度の調節ができない点が一つと、もう一つは stopを押すまでは無限ループの状態になっているのと同じになって繰り返しが連続されてリソースを食いすぎてしまう。 無限に近いループを利用した様なプログラムは書くべきではない。という事です。
この他にも、ユーザー入力によって条件を満たしたり、画像が全部ロードされたのを確認して条件を満たすような whileループを作ると、ループを繰り返すのに忙しくて ユーザーの入力を受け付けられなかったり 画像がロードされる余裕が無くなったりします。 なるべく、スクリプト内で自ずから満たされる様な条件の場合にforループ、whileループを使ってください。


do 〜 while

top
do 〜 while〜 ループは while とほとんど同じです。少し違うのは while(条件)部分が 後ろから条件を付けている点です。 まず形を書きます。
do{
   ステートメント;
}while(条件);

この do〜while〜では、プログラムの流れとしてまず do ブロックが実行されます。 doブロックのステートメントが実行されてから while(条件)の条件評価をします。 条件が 真(true)であれば、do ブロックを実行します。 つまり、条件が 偽(false)ではじかれたとしても、少なくとも一度はdoブロックのステートメントが実行されます。 日本語で言うと次のような感じでしょうか?
『 実行して、それでもまだ真なら もう一度実行、それでもまだ真なら・・・・ 』
つまり、実行してから 繰り返すかの評価を行うわけです。 whileループの場合はまず条件が合えば、ループに入ります。 ステートメント部分を実行してからどうするか決めるか、実行する前にどうするか決めるかが whileと do〜whileの違いです。
do ブロックの中括弧 { } は ステートメントが1つの時は省く事ができます。
あともwhileと同じで カウンタ変数初期化、カウンタ更新がないので 必ず自分でカウンタなり条件を満たせるような処理を作ってください。

◆単純な例 数値カウンタ
var i=0;
do {
    window.status = i;
    i++;
}while(i<10);
まず、カウンタとして使う変数を、ループ外で初期値設定します。 次に doブロックのステートメントを実行します。 次に、繰り返しを行うかの条件を評価します。
◆引算を使った、割り算の商と余
var n=45; //引かれる数
var i=4; //引く数
var y=0; //ループ回数を変数に

do{
n = n - i;
y++;
}while(n>=i);

document.write("商"+y);
document.write("余り"+n);
do〜whileでは doブロックをまず実行して それでもまだ引けるようであれば繰り返します。 この例では 初期値で n が iより小さくても 一度は引算をされます。 商は必ず1以上になってしまいます。 つまり、この場合 この引算式の商余は正確でない場合があると言う事になります。 nが常にi以上である事が条件となります。

この様に、whileの方が適切な場合もありますので、 do〜whileは 実行してもまだ満たされない場合は・・・・と言う感じで使う物だと覚えてください。


break

top
breakステートメントは、ループを抜ける時に使います。
すでに for、for〜in、while、do〜while ループの説明で説明は済んでいます。

◆ループを抜けると言う事は?
for(i=0; i<100; i++){
if(i==50){ if(!confirm('続けますか?')){break;} }
}
alert("終了しました");
この場合 confirmボックスに はい で答えると breakでループを抜けますが ループを抜けるとforループの次に書かれている alert() が実行されます。 ループを抜けない場合もループが自動終了してからalert()が実行されます。 従ってループを抜けた時だけに実行したいステートメントは breakの直前に書く必要があります。
if(i==50){ if(!confirm('続けますか?')){ domes(); break;} }
これで domes()と言う関数へ処理が渡ります。

また、ループが2重3重になっている様な場合は、breakの書き込んであるループのみを抜け出します。
$navi = navigator.userAgent;
$color = new array("#0000cc","#cc0000","#009900");
for(i=1; i<4; i++){ // #1
    document.write("<font color=" + $color[i]+ ">");
    for(n=1; n<8; n++){ // #2
        if(n==5 && $navi.indexOf('MSIE') < 0 ){ break;}
        document.write("<font size=" + n + ">artemis</font>");
    }
    document.write("</font><br>");
}
for文の2重ループです。 2重ループでは 外側のループ#1 の各回につき内側のループ#2が完全実行されます。 従って内側のループ#2は この場合3回実行される事になります。 #2では カウンタ変数が5の時に msie以外は breakしてループを抜けるので msie以外では内側のループはfor(n=1;n<5;n++) と同じ事になります。 外側のループ#1は 関係なくカウンタ1〜3までの3回実行されます。

◆break label (nn4、ie4以上のみ)
breakには終了するループを指定する事ができるように、break label と言う方法があります。 例えば直前の例で使われている breakは 内側の#2のループを抜けるだけです。 しかしこの時に一番外側のループも辞めたい場合に label を使います。
$navi = navigator.userAgent;
$color = new array("#0000cc","#cc0000","#009900");
myroop:
for(i=1; i<4; i++){ // #1
    document.write("<font color=" + $color[i]+ ">");
    for(n=1; n<8; n++){ // #2
        if(n==5 && $navi.indexOf('MSIE') < 0 ){ break myroop;}
        document.write("<font size=" + n + ">artemis</font>");
    }
    document.write("</font><br>");
}
breakの後ろにラベルを指定する時は 半角あけてラベル名を書きます。 実際にラベルを貼りつける場所にはラベル名:の様にコロンを後ろに付けます。 ラベルを付け、それを指定するbreakを使う事で 好きなループを抜けられます。 が、しかし、nn4、ie4以上なので それ以外のブラウザでは ラベル自体が記述ミスとして扱われます。


continue

top
continueステートメントは、 ループのステートメントブロックで使います。 continueがあると、それ以下のステートメントの実行をせずに、ループの先頭に戻り 通常の繰り返しのように繰り返されます。 使えるループはのは for、for〜in、while、do〜while です。
$list = new Array(10);
for(i=0; i<10; i++){
    if(i==4){ continue; }
    $list[i] = "page" + i + ".html";
}
この場合、$list[4] 以外の配列要素には $list[番号] = page番号.html と言う ファイル名が文字列として代入されますが、$list[4]には何も代入されません。 4の場合 continueがあるので、次のステートメントを実行せずに次回のループに行ってしまいます。 ある特定の場合無視して欲しい場合等にこれを使います。

ただし気を付けねばならない事があります。
forループ、for〜inループは このループ全体をセーブするカウンタ更新が基本で用意されています。 従って、continueの後に 頭に戻るとカウンタ更新をして、次の回にはいります。 for〜inの場合は自動で次の配列要素を変数に代入してストーとメント実行に移ります。 つまり、continueを使っても問題なく動作します。
whileループ、do〜whileループでは このループ自体にカウンタ更新が用意されていない為 自分でカウンタ更新を用意しているはずですが、continueより後にカウンタ更新があると カウンタの更新がされません。つまり、無限ループに陥ります。 通常行うべき処理をしてからカウンタ更新をしていると思いますので continueは その行うべき処理を行わないわけですから、continueより後にカウンタ更新が 書かれてしまうのが通常の処理の流れだと思います。 そこで continue;を使う場合は、使う直前にカウンタ更新できるような配慮をしてください。 大抵の場合次の例のように 条件によって continueにするでしょうから、 continueを記述する前にカウンタ更新も追記してください。
var $list = new Array(10);
var i=0;
while(i<10){
    if(i==4){ i++; continue; }
    $list[i] = "page" + i + ".html";
    i++;
}
ここで i==4の場合の i++; が無いと i が 4の状態のまま再度whileループへ入ります。 すると、またcontinueになり、また 4のまま whileループへ・・・と言う無限ループにはまります。

◆continue label (nn4、ie4以上)
通常 continueの時に そこで処理を中断してループの先頭にジャンプして 次の繰り返しを行うわけですが その時にジャンプするループの先頭を指定する事ができます。その指定をするのがラベルです。
$navi = navigator.userAgent;
$color = new array("#0000cc","#cc0000","#009900");
myroop:
for(i=1; i<4; i++){ // #1
    document.write("<font color=" + $color[i]+ ">");
    for(n=1; n<8; n++){ // #2
        if(n==5 && $navi.indexOf('MSIE') < 0 ){ continue myroop;}
        document.write("<font size=" + n + ">artemis</font>");
    }
    document.write("</font><br>");
}
この場合 msie以外では 内側 forループの下に書いてある
document.write("</font><br>"); は一度も実行されません。
ここではこれは不都合ですが、そういう状況の時に continue labelをうまく使ってください。


label

top
lable は 特定のジャンプ先の為の位置を指定します。
使い方は switch、break、continue を見てください。 特定のステートメントにラベルを付ける事で、 labelへジャンプする事のできるステートメントで このラベル位置へジャンプする事ができます。
nn4、ie4以上で有効ですが、それ以外では 記述ミス扱いされますので 注意して使ってください。


with

top
with(オブジェクト)は、withステートメントブロックで使う既定オブジェクトを決めてしまいす。 これにより、オブジェクト指定部分を省く事ができます。 同じオブジェクト操作のステートメントが複数ある場合等に、ステートメントを簡素化する為に使います。

//sample #1
with (document){
write('あなたのブラウザは<br>');
write(navigator.appName);
write('です');
}

//sample #2
var $newwindow = window.open("","","width=300,height=100");
with ($newwindow.document) {
open();
writeln('<html>');
writeln('<body text="#ffffff">');
writeln('このウィンドウは<br>');
writeln('navigation window です');
writeln('</body>');
writeln('</html>');
close();
bgcolor = "#990000";
}
sample #1、#2 同じような例ですが。document.write() の様な時には連続で 何行も同じように書く事が多いですね。この様な時に簡略化する為に ターゲットのオブジェクトをwith(オブジェクト)指定します。 これによりこのwithブロックで出てくるプロパティやメソッドは このオブジェクトに対して書かれている事が暗黙になります。

sample #2では 新たにウィンドウを開き、そのウィンドウのドキュメントに対して書込みしています。 オブジェクトとしては window.openで新しいwindowを$newwindowと定義していますので $newwindow.document が オブジェクトと言う事になります。

新しいウィンドウをjavascriptで開いて、そのウィンドウを分離式メニューにする時などは かなりの書き込み量があります。そんな時に使ってください。

withブロック中に他のオブジェクトの操作を書く必要がある場合は、 きちんと操作したいオブジェクト名から書けば問題なく普通に動くと思います。


this

top
javascript中で現在のオブジェクトを指す言葉となります。
netscapeのリファレンスで演算子の部類で紹介されていましたので、演算子のページの特殊演算子として 解説してあります。
thisは日本語で書いても『これ』と言う意味ですから、使われる場所によって指す物が変ってきます。 この辺を間違わないようにしないといけません。
この他にステートメントとして function、return、var 等がありますが これらはそれぞれの用途専用のページ 関数、関数、変数 のページで 使い方も含めて説明してあります。

←前 次→



専用ページから申し込むと
So-netより高い3万円CB

案ずるより産むが易し
使ってみれば疑問も解決

XREA+ (plus) 206円/月
( お試し7日間 )

CORE SERVER 428円/月
( お試し15日間 )

ロリポップ 270円/月
( お試し期間10日間 )

ヘテムル 1620円/月
( お試し期間15日間 )

さくら 129円/月
( お試し期間2週間 )

無駄な高額ドメイン管理料金払ってませんか?

バリュードメイン
ムームードメイン