uhyohyo.net

JavaScript初級者から中級者になろう

基礎第五回

このページの最終更新日:

イベント

今回はイベントについて解説します。イベントといっても、お祭りとかではありません。

今まではJavaScriptの文法等について解説してきましたが、今回はちょっと毛色が違い、HTMLとかウェブに関連する内容です。JavaScriptでのイベントとは、何かが起こったときにJavaScriptが動くことです。

何かが起こるとは、例えばクリックしたとか、そういうことです。サンプルを見てみましょう。今回はHTMLが絡んでくるので久しぶりにHTMLを全部示します。

<!doctype html>
<html>
  <head>
    <title>test</title>
    <style>
      p {
        width: 200px;
        height: 200px;
        background-color: #ffff00;
      }
    </style>
  </head>
  <body>
    <p onclick="alert('click');">test</p>
  </body>
</html>

実行してみても、黄色い長方形があるだけで何も起こりません。

サンプルも、いつもとは何か違うようです。そもそもscript要素がありませんね。しかし、pタグにonclick属性という属性がついています。

なお、黄色い長方形はp要素です。style要素で設定したスタイルシートによってこのように表示されています。

今回重要なのはonclick属性です。onclick属性の中にはJavaScriptが書かれています。実は、このonclick属性の中身が、クリックされると実行されます

今回、このonclick属性はpタグについているので、p要素をクリックしたときに実行されるというわけです。これはクリックされる度に何回でも実行されます。

一応中身を見てみます。

alert('click');

普通にアラートを表示しているだけなのですが、その引数が実はまだ説明していませんね。

クリックすると「click」と表示されるのでこれは文字列のようですが、"ではなく'で囲まれています。

実は、'で囲んでも文字列になります。ですから、'test'というのは"test"というのと同じ意味です。

HTMLの属性が"で囲まれているので、その中で再び"を使うとわからなくなってしまいます。そこで、異なる記号を使うようにしているのです。

また、次のサンプルを見てみましょう。

<!doctype html>
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <script type="text/javascript">
function aaa(){
    alert('click');
}
    </script>
    <form action="#">
      <p><input type="button" value="click!" onclick="aaa();"></p>
    </form>
  </body>
</html>

画面にボタンが現れ、クリックするとアラートが出ます。

このように、ボタンにonclickを付けて押されると何か処理をするというのもよくあります。

また、今回はちゃんとscript要素もあります。しかし、中身を見てみると、関数aaaを作っているだけで何もしていません。実は、この関数aaaはinputのonclick属性内で使われています。処理が長くなる場合は、このようにonclick内では関数呼び出しをするだけにして、関数内で多くの処理をする方法がよいです。

短いですが、今回のイベントの解説はこれで終了します。ずっとアラートで結果を見るだけというのもつまらないので、これを解説してみました。

繰り返し

同じ処理を何度も繰り返したいということはよくあります。そういう時のための書き方があります。今回は、そのうちwhile文を解説します。

次のサンプルを見てみましょう。

var i = 0;
while(i < 5){
    alert(i);
    i++;
}

「0」「1」「2」「3」「4」と5回アラートが出ました。

しかし、スクリプト中にalertは1度しかありません。当然、whileが関係しています。今回はこれを解説していきます。

このwhile文は次のように書きます。

while(  ){
    文(いくつでも)
}

それでは、while文のはたらきを解説します。

while文は、与えられたが真である間、中の文を繰り返し実行します。

より詳しく説明すると、while文の行に来ると、まず括弧の中のが計算されます。そして、だった場合{ 〜 }の文を実行し、だった場合、そのまま処理を終了します。

真の場合に{ 〜 }の処理を全て実行すると、再びの評価に戻ります。

そしてまた条件を判断し、真の場合実行してまた戻ります。条件に使う式が同じだと永遠に繰り返すように見えますが、そういうわけでもありません。判断に使う式に変数などを使えば、結果が変わる可能性があります。上のサンプルがその例です。

それでは、このサンプルの動作を見てみましょう。

まず、変数iに0を代入します。次の行で、i < 5は、iは0で5より小さいのでtrueを返します。つまりです。

よって、中の文が実行されます。中の文では、iをアラートで表示します。いま、iは0なので、0が表示されます。

その次の行を見てみましょう。見たことがない処理ですね。しかし、この文は「iに1をたす」という意味です。詳しくは後で解説します。よって、iはここで1になります。

さて、ここで処理が終わったので条件式の評価に戻ります。i < 5」は同じくtrueを返すので、またアラートが表示されiが1増えて2になります。

この繰り返しは、i < 5がfalseを返すようになるまで続きます。つまりそれは、iが5になったときです。

iが4になるまで繰り返してアラートが4を表示したところから追ってみましょう。

i++;の文により、iが5になります。再び条件式を評価すると、i < 5がfalseを返すためここで処理が終了します。よって、5のアラートは表示されることなくwhile文は終了します。

このようにwhile文を使うと同じ処理を何度も繰り返すことができます。

ただし、while文を使う場合必ず処理がいつか終わるようにしましょう。いつまでも式が真のままで繰り返し続けると、JavaScriptの処理がいつまでたっても終わらず、結果としてブラウザがフリーズしてしまうことがあり危険です。

インクリメント・デクリメント

さっき出てきたi++;の解説をします。実は、++が新しい演算子で、インクリメント演算子といいます。

しかし、今までと多少様子が違います。今までの演算子は3 + 5とかa = 7のように左右に値がありました。

それが、今回は左に変数iがあるのみで右には何もありません。実は、この演算子は、オペランドが1つしかありません。

ちなみに、このようにオペランドが1つしかない演算子を単項演算子といいます。対して、2つある演算子は二項演算子といいます。

それでは、このインクリメント演算子のはたらきですが、上でちらと解説したように変数に1を足します。つまり、

i++;
i+=1;

の2つの文は同じ動作をしていることになります。

ちなみに、++i;のように変数の前につけることもできます。変数に1を足すのは同じです。

ただし、1つだけ違いがあります。それは返す値の違いです。演算子が前にあると足した後の値を返し、後にあると足す前の値を返します。

さらに、--という演算子があります。インクリメント演算子が変数に1を足すのに対し、これは変数から1を引く演算子で、デクリメント演算子といいます。使い方はまったく同じです。

break文・continue文

繰り返し(ループともいいます)を操作するための文があります。次のサンプルを見てみましょう。

var i = 0;
while(true){
    i++;
    if(i < 2){
        continue;
    }
    alert(i);
    if(i > 5){
        break;
    }
}

「2」「3」「4」「5」「6」と5回アラートが出ました。

気づく人は気づいたと思いますが、whileの式がtrueとなっています。つまり必ず真となっています。これはたいへん危険なはずです。

しかし、特にフリーズなどすることなく正常に5回アラートが出たと思います。これには、新しく出てきた「break」と「continue」の2つが関係しています。

さて、continueの解説をします。このcontinue文は、{ 〜 }の実行を今回は終了するというはたらきをします。つまり、while文の{ 〜 }の中の実行を途中で終了し、次のループを最初から判定します。もちろん、次のループを実行する前にも条件式の判定があり、偽になっていたらそこでループが終了になります。

breakは、ループを強制的に終了するというはたらきをします。continueとは異なり、breakはその場でループ全体(今回はでwhile文全体)が終了します。breakのおかげで、while文の条件がtrueでもループから抜けることができました。

では、実行の様子を詳しく追っていきましょう。

まず変数iに0を代入し、whileの行に入ります。ここで式がtrueなので、ループに入ります。

ループの最初でiに1を足しているので、ここでiの値は1です。その次の行のif文でi < 2はtrueを返し真なので、中の文が実行されます。

ここで、continue文が実行されるので、今回のループは終了し、whileの行まで戻ります。さて、ループを初めからやり直すと、iにiを足してiが2になります。

今度はifの条件は偽なのでこの中のcontinueは実行されず、次の行に進みます。ここでalertでiが表示されるので、「2」が表示されます。

次のif文のi > 5は偽なので、breakは実行されず最初に戻ります。その後iが3になり同様の処理がされます。i < 2が真になることはもう二度とないですね。よってalertで3が表示されます。

その後のi > 5が真になるのはiが6になったときです。だから、「3」「4」「5」まで同様に表示されます。

「5」を表示した後もまだi > 5は偽なので次にiが6になります。

ここで、「6」を表示した後次のifが真になりbreakが実行されます。breakはループを終了するというものなので、ここでwhileが終了します。

少し長かったですが、これが一連の流れです。

do 〜 while文

さて、while文には仲間みたいなのがいます。do 〜 while文です。サンプルを見てみましょう。

var i=0;
do{
    alert(i);
    i++;
}while(i < 3);

「0」「1」「2」とアラートが出ます。

実は、while( 式 ){ 〜 }{ 〜 }がwhileの後ろではなく前についただけです。つまり、次のようになります。

do{
    文(いくつでも)
}while( 式 )

ただし、最初にdoをつける必要があります。

ただのwhileとの違いですが、do 〜 while文は中の文を先に実行してから式の真偽を判定します。これの違いは、次のような場合に現れてきます。

do{
    alert("test");
}while(false);

「test」とアラートが出ます。

これは、まず中の処理、つまりalertを実行して、それからwhileの判定をして偽なのでループを終了するという処理からきています。これが、ただのwhile文だったらどうでしょう。

while(false){
    alert("test");
}

アラートは出ません。

まずwhileの条件文が判定されていきなり偽なので、一度も中の処理が実行されずに処理が終わるからです。このように、条件がいきなり偽だった場合に、1度実行されるか1度も実行されないかの違いがあります。