最終更新日



JavaScriptの基本

[関連ページ] 
  JavaScript応用1   DOM(Document Object Model)とstyleの変更により、動きをあたえる例。
  JavaScript応用2   DOMにより、直接、htmlを書き変える例。
  JavaScriptのプログラム 学生向けにまとめたページ。

1 はじめに

1 概要・各章の紹介

JavaScriptはホームページ上で動く面白いプログラム言語です。インタープリータ = 逐次翻訳型プログラム言語で、コンパイルの必要もなく、HTML文書の中に書いて、直ちにブラウザ上で動かす ことができて、動作環境の設定は一切必要がなく、ホームページ作成のツールに頼らず、htmlのタグを自分で書いてきた方々には、ホームページ作成の延長でできて、とっつきやすいものです。

ホームページに動きを与えるダイナミックHTML、フォームのTextオブジェクトへの入出力やフォームの入力チェックなどに向いています。

「JavaScriptというとダイナミックHTML」ですが、それは、JavaScriptの応用1 およびJavaScriptの応用2 に書くこととして、まずは、どの言語にもあるプログラム言語としての基本をマスターしておくことは必要でしょう。変数、配列、繰り返し処理、if文やswitch文による条件判定、関数、そして現代的言語の特徴であるオブジェクト指向などを 2 JavaScriptの基本 で展開します。

次に、その延長線上で、フォームとイベントハンドラで、テキスト・ボックスへの入出力を扱います。
3 おみくじ・さいころの目 は、ややお遊び的なものです。

4 配列のソートなど は2をフォームとイベントハンドラで扱ったもので、入力する値をいろいろ変えることができるようになります。

5 16進数変換・文字コード はコンピュータの基礎としてと重要な2進、16進数、文字コード(内部表現)を扱います。10進数を入力して、2進数や16進数に変換するとか、漢字を含むさまざまな文字を入力して、コンピュータの中ではどう表現されているのかを実感していだきたい。大文字、小文字の区別、半角と全角の違いも分かるでしょう。オブジェクトのメソッドや組み込み関数などもいろいろと紹介します。

6 Javascript命令・オブジェクト・DOM まとめ は各章で、その都度、ふれてきたことですが、一応まとめておきます。DOMについては、5章でちょっとふれた程度で、主に応用1、2でやることですが、りますが。

[お断り] ソースを見ていただくため、2,3,4,5ではいずれもhtmlソースをtxt形式で保存したものにリンクをはりました。Netscapeでは正しくエディタが呼び出され、意図した通りになります。以前はそんなことかなかったと思うのですが、インターネット・エクスプローラでは、それも拡張子htmlのものと同様、実行画面になってしまいます。いずれ、解決されるだろうと、そのままにしておきます。インターネット・エクスプローラで、ソースを見るには、実行画面から、表示-ソースとしてください。

2 参考図書・URL

私ははじめてJavaScriptにとりこむとき、参考にしたのは
 「ホームページに今すぐ活かせるJavaScript」
    松尾・古籏著 インプレス 1980円 2000年11月発行」
 ともかくやってみようという私好みのスタイルで書かれており、CD-ROMつきの例文も豊富、比較的安いし、いいのではないかと思います。

しかし、少し、自分でなにかしようとすると、オブジェクトとか組み込み関数とかが辞典的に整理された本も必要になります。私は下記を購入しました。
 「HTML&CSS&JavaScript辞典」
    岡蔵・半場著 秀和システム  2002/4 初版第2刷2380円

とほほのJavaScriptリファレンス が詳しく、よく整理されています。オブジェクトについても詳しく、DOMについてもふれられています。

3 デバッグ環境

JavaScriptは、html文の中に書いて、インターネット・エクスプローラやネットスケーブなどのブラウザで実行できる手軽さですが、エラーをチョックするには、前者の場合、ツール-インターネット・オプション-詳細設定-ブラウズ-「スクリプトのエラーごとに通知を表示する」 にチェックをいれておきます。後者は、ツール-Web開発-JavaScriptコンソールとします。

ホームページに今すぐ活かせるJavaScript support の第一部の繰り返しの例題をはじめ、基本的な事柄を扱っています。しかし、日常生活的な簡単なものが多く、次の2章に、くり返しの補強のため、アルゴリズムの少し難しい例をいくつか出します。

2 JavaScriptの基本

コンピュータの最大の特徴は、何万回、何億回もの繰り返し処理をあきもせず、高速で処理してくれるところにあると思います。同じことをしてもしかたがないから、変数ないし配列で値をかえながら....。場合によっては、条件が満たされたから、処理を打ち切場合もあるでしょう。if文やswitch文による条件分岐も必要になります。以下は、そうした大事な繰り返し処理(forとwhile)の事例です。

なお、プログラム例は2章では、直接ソースで出しますが、テキスト形式でプログラムのみを集めた program.txt でもご覧いただけるようにします。

1. 1から1000までの和

SUM = 1 + 2 + 3+.........+n
SUM = n+(n-1)+(n-2)+.......+1
------------------------------------
2*SUM = (n+1)+(n+1)+..........+(n+1) = n*(n+1)
SUM = n*(n+1)/2
という「等差級数の和」といういかめしい名前の公式ですが、大数学者のガウスや戦後すぐ、日本人初のノーベル物理学賞をとられた湯川秀樹博士が、中学生のときに独力で見出したということで有名なものです。

下記は、1000までの和、繰り返しのforループで、コンピュータが逐一足しこんでくれた結果ですが、上の公式を使うと、いとも簡単に検算できるというものです。

プログラムソース
<html><head>
<title>1からnまでの和</title>
<head>
<body>
<SCRIPT type="text/JavaScript">
<!--
// 1.  1から1000までの和
var sum=0;
var n=1000;
for (i=1; i<=n; i++) {
	sum +=i; //sum += sum +i の省略形 
}
document.write("1から " , i - 1 ,  "までの和 = " , sum);
//-->
</SCRIPT>
</body></html>

for (i=1; i<=n; i++) の記述は、カウンタiの初期値、条件判定、カウンタiの足しこみで、条件が満たされている間は、ブロック({ ...}をいう)内の処理を繰り返します。

実行結果
1から 1000までの和 = 500500

なお、処理結果を画面に表示するのに、最初からdocument.write()というようなのが出てきます。JavaScriptは、ホームページ上で動くプログラム言語で、ブラウザが持っているオブジェクト(部品)をそのまま利用できるようです。documentも、そのひとつ、「ブラウザの画面」をあらわすオブジェクト、あるいは、HTML文書そのものを扱うオブジェクト、writeはそのメソッド(関数) ということです。

なお、document.writeの()内のカンマ(,)は文字列結合。+ もよく使われます。文字列結合の詳しい説明は、この章の5でやります。

JavaScriptのオブジェクトは簡易型、他の本格的言語に比べると簡単ではありますがそれでも、オブジェクトという概念を理解するのはなかなか大変だし、JavaScriptには、ブラウザが持つもの以外にも、JavaScript独自の組み込みオブジェクト(Date,Math,Array,String,Numberなど)もあり、全貌を掴むのは大変です。

最初は、画面になにか表示させたいと思ったら、document.write()と書くものと、理屈抜きでまず慣れるのがいいでしょう。(次の2節、3節にも、4章の1,3などにも出てくるので、次第に説明を詳しくしていきます。)

2. 配列で与えたデータの中の最大値

例では、data2=new Array(300,200,700,1000,500) という5ケの数値の中の最大値を求めるものです。
配列Arrayは、JavaScriptが持つオブジェクトで、Arrayオブジェクトをひな型とした新しい配列を作るには、new演算子というものを使います。これまた、最初はそういうものと素直に受け取るのがいいですね。JavaScript独自の組み込みオブジェクトというのも、早速出てきました。

以下、head部とbody部の<SCRIPT type="text/JavaScript">などの記述は省略 します。

プログラムソース
// 2.  配列で与えたデータの中の最大値
data2=new Array(300,200,700,1000,500);
var max=data2[0]; //配列の最初の要素を最大と仮にしておく
for (i=1; i<data2.length; i++) {
	if (data2[i]>max) max=data2[i];
}
document.write("配列データ = " + data2 +"<BR>");
document.write("  Max = " + max);

変数 maxを最初は配列の最初の要素としておいて、
    var max=data2[0];
 forループの中で、if文で配列の各要素とmaxとを比較して、大きい方をmaxにしていくだけです。

実行結果
配列データ = 300,200,700,1000,500 Max = 1000

この例は、「if文で配列の各要素とmaxとを比較して、大きい方をmax」としましたが、JavaScript組み込みオブジェクトに、数学的処理を集めたMathオブジェクトがあります。その中に、2つの数のうち、大きい方を取り出すmax()というメソッドがあります。Math.max()というように、オブジェクト.メソッドという使い方をします。メソッドとは動作を記述するもので、一種の関数です。

プログラムソース
// 2.2  最大値その2、Math.max()を利用
data2=new Array(300,200,700,1000,500);
var max=data2[0]; 
for (i=1; i<data2.length; i++) {
	max=Math.max(data2[i],max);
}
document.write("配列データ = " + data2 +"<BR>");
document.write("  Max = " + max);

実行結果はif文を使ったものと同じになります。

3. 配列データのソート

こんどは配列データを小さい順に並べ替え(ソート)てみましょう。二重の繰り返しを使っていますが、外側のforの繰り返しで、iは最初、配列の長さ、結局、そこでの最大値を求めて、配列の一番右にもってくる、次に、i-1 での最大値を右にもってくるということをしています。途中結果を打ち出してみると、よくわかります。

プログラムソース
//3 ソート(配列のデータ)
	data=new Array(10,100,50,60,30,80,70,40);
        document.write("データ " + data  + "<br><br>");
	for (i=data.length;i<=0;i--) {
  	    for (j=0;j<i;j++){
		if (data[j]>data[j+1]) {
			var temp =data[j];
			data[j]=data[j+1];
			data[j+1]=temp;
		}
	    }	     		
            document.write("j= " + j + " ソート途中 " + data + "<br>");
       }
        document.write("<br> ソート結果 " + data);

実行結果

二重の繰り返しと、問題処理の考え方(アルゴリズム)も難解ですが、for文の中にあるdata.lengthは配列オブジェクトのプロパティ(属性、一種の変数)に関する説明も簡単ではありません。dataは、new Arrayで作り出される配列オブジェクト ではありますが、Arrayも配列オブジェクトという言い方をします。Arrayは、配列を作り出すおおもとのオブジェクト、型紙とかテンプレート(ひな型)であり、dataはそのひな型から作り出され、Arrayオブジェクトの持つメソッド、プロパティをそのまま受け継いだ 実例(インスタンス) です。JavaScriptでは、ひな紙もインスタンスもオブジェクトといって,区別がやや曖昧ですが、Javaなどでは、ひな型に相当するものは、クラスとして両者は明確に区別されます。data.lengthは配列の大きさを取得するプロパティで、プログラム例では、5となります。

Mathオブジェクトでは、Math.max()のように、おおもとのオブジェクト.メソッドと書きました。これには、異なる実例というのはないからです。Javaでは、インスタンスに対して静的オブジェクトといっています。配列の実例は無数にあります。こういうときは、インスタンス・オブジェクト.メソットないしプロパティと書きます。Mathの場合と違って、Array.lengthとは書かず、data.lengthとするのはそのためです。

これらのオブジェクトについては、1章で紹介したとほほのJavaScriptリファレンス 参照のこと。どういうオブジェクトがあり、あるオブジェクトにどのようなメソット、プロパティがあるかが分かりやすい。それを知らずには、プログラムは不可能です。また、自分で作ると長いプログラムとなるょに、たったの1行でできたりします(後に、実例をいくつか出します)。

4. 乱数発生とソート

今度は、配列(Array)オブジェクトのsortメソッド を使います。配列にも乱数を入れます。乱数発生は、Math.random()。これも、Mathオブジェクトのメソッドで、0から1までの乱数を発生させます。分かりやすいように1000倍し、Math.floor()メソッドで、最も近い整数にしています。

data2.sort(SortSet)が、配列のインスタンス・オブジェクトのメソットです。

プログラムソース
// 4. 乱数発生とソート
var n=10;
data2=new Array();
for (i=0; i<n; i++) {
	data2[i] = Math.floor(Math.random()*1000);
         // Math.floor()メソッドで、最も近い整数
         // Math.random() 0から1までの乱数発生
}
//ソート前の乱数データ
document.write("乱数データ = " + data2 + "<BR>");
//数値としてソートするときの比較関数、昇順の場合
function SortSet(a,b){return a - b}
document.write("数値Sort = " + data2.sort(SortSet) + "<BR>");
//文字列としてソートすると、
document.write("文字列Sort = " + data2.sort());

ソートメソッド、sort()は、配列の要素を文字列として扱い、辞書編集法にしたがってソートされます。10,120,89などとなり、10,89,120を期待していると、意図に反する結果になることもあります。

数値として扱うときは、ソースにあるように、sort(比較関数) とします(小さい順(昇順)にソートする場合の例)。次の実行例で、文字列ソートと数値ソートの両者を出しておきますが、次の4章 のソートの事例で、テキスト・ボックスに値を入力して、両者の違いを直接、確かめてみてください。

実行結果

5. 2進数変換

例えば、10進数の13を2進数で表現すると、
 1101 = 23 + 22 +0*21 +1
となります。

13を2で割ると、その余りが2進数の最初の桁の値、その商、6を2で割ると今度は余りは0、これが、2の桁の値というようにして、変換していきます。下記は、8ビットの最大値1255を変換した例です。繰り返しの途中経過も出力しています。

プログラムソース
// 5. 2進数変換
    var n10=255;
    var m10=n10;           //n10は値が変わるので最初のデータを保存
    var n2=0;
    var ans ="";      //余りを文字列で結合し、2進数文字列を格納
   document.write("変換する10進数 n10= " + n10 + "<BR><BR>");
    while (n10 > 0) {
	n2=n10%2;      //2で割った余りを変数n2に格納
        n10=(n10-n2)/2;   //2で割った商(整数)、繰り返すときの次のn10
	ans=n2 + ans;   //余りを文字列で結合し、2進数文字列を格納
    	document.write("n10= "+ n10 +" n2= "+ n2 + " ans= "+ ans  + "<BR>");    }
    if (n10 == 1) {
        ans= 1 + ans;   //最後の商が1なら、2進数の最大の桁になる
    }
   document.write("<BR>10進数 " + m10 + "の2進数は " + ans + "<BR>"); 
                          //変換した2進数の出力

実行結果

余りを求める演算子は % です。この余りは数値ですが、順次文字列結合していきます。その手段は簡単で、答えをいれる変数、ansを
 var ans =" "のように文字列を格納する変数として用意しておいて、
 ans= n2 + ans のごとく、+ で結合していくだけなのです。

右辺に、ひとつでも、文字列が含まれていると、+ は、数同士の足し算ではなく、文字列結合 となります。n2は数字のままでもいいのです。n2=1 ans="01" とすると、ans= n2 + ans は、文字列 "101" になります。なお、文字列と数値との違いについては、5章 で実際にトライして確かめてください。

これまで詳しい説明をしてこなかった、document.writeの中の + も同様で、ひとつの文字列にまとめていきます。変数には、"" をつけず、その中味をいれ、""のついているものは、その通りに出力するので、 + "" がいりまじって複雑にみえますが、ひとつひとつを上記のansと同じようにみていくとわかるでしょう。なお、この章の1では、+ ではなく、, を使いました。どちらでもいいのですが、他の言語では、+ だけというのが一般的です。

さて、この例題の繰り返しは、forではなく、while を使っています。whileはforと違って、iのようなカウンタ変数を必要とせず、条件を満たす限り繰り返します。nまでの和の例では、カウンタ変数自体を足しこんでいるし、配列を使う例では、その添え字をカウンタ変数で順次変えていくことが多いですから、forが向いていますが、この2進変換では、繰り返し回数自体が不明、whileがいいですね。明らかに大きな繰り返し回数を設定しておいて、条件が満たされたら、breakステートメントで繰り返しを打ち切るとして、forが使えないことはないですが。

3 おみくじ・サイコロの目

Javascriptの基本として、これまで、変数、配列、繰り返し、関数、if、switch文などのプログラミングの基本とオブジェクト(document.write()、new Array()、Math.max()、Math.floor()、Math.random()、data.length、data2.sort())を見てきました。オブジェクトには、メソッドとプロバティがある、ひな型のオブジェクト名をそのまま使うMathと、インスタンスを作ってから、そのインスタンス・オブジェクトを使うArrayのようなものがあることもみてきました。

少し、視点を変えて、フォームのテキスト・ボックスへの入力とイベント・ハンドラーをみていきます。フォーム自体はタグで、HTMLの範疇ですが、HTMLだけでは使いようがありません。JavaScriptやCGIを使って、はじめて意味が出てきます。

これまで、やや数学的な例題で説明してきましたがおみくじのようなお遊び的な例で、新しく、フォームとイベントについてみていきましょう。

プログラム例は、おみくじ・サイコロの目 にあります。プログラム自体は、「表示−ソース」 でもみられます。しかも、2つのプログラムのうち、ひとつはここに全体を出しますが、念のため、omikuji-form.txt にもおきます。

1. おみくじ・サイコロの目(フォーム・イベントハンドラ)

配列オブジェクト、Mathオブジェクトのfloorとrandomメソッドを使っています。いずれも、2-4 乱数のソートで使ったのです。Math.random()*6と6をかけているのは、おみくじの配列の大きさが"大吉"から"大凶"まで6ケだからです。それを整数化したものを配列の添え字とすれば、"大吉"とか,"吉"とかになるから、それをフォームのテキストボックスに、document.myform.text2.valueとして出力しています(詳しくは後述)。

プログラム例は、前述したように、おみくじ・サイコロの目 にあります。神社のおみくじとは違って、大凶も遠慮なく出ますが、それは気にせず実行してみてください。

おみくじのプログラム全体をだします、サイサロもよく似ています。

<html><head>
<title<おみくじ</title>
<script type="text/javascript">
<!--
var omikuji = new Array("大吉","吉","小吉","小凶","凶","大凶")
function Hantei() {
   var i = Math.floor(Math.random()*6)
   document.myform.text2.value=omikuji[i];
   //or main.innerText=omikuji[i];
}
function Sakujyo() {
   document.myform.text2.value="";
}
//--<
</script></head>
<body style="background='yellow';"<
<h1>おみくじ>/h1<
<div id="main"> <!--innerTextを使わないときは不要。-->
<form name="myform">
<p style="color:red;font-size:large;">
今日の運勢:<input type="button" value="さて?" onclick="Hantei()"></p>
<input type="text" name="text2"><input type="button" value="削除" onclick="Sakujyo()"></form>
<pre style="color:blue;">
   大吉  "すべてうまくいくが、調子に乗らぬこと"
   吉    "小さな喜び事あり。争いを避けること"
   小吉  "これからが肝心。今の調子でがんばれ"
   小凶  "思わぬところに落とし穴が。用心すべし"
   凶    "何事も辛抱"
   大凶  "今が最悪期。これから徐々に運が上向く"
</pre>
<pre style="color:green;">
大吉から大凶まで、すべて出る確率は同じ(乱数使用)。
参考 http://www.msu.edu/~okadakat/jskowaza.htm 
</body></html>

フォームとはhtmlのタグのひとつです。テキスト・ボックス、コマンド・ボタンをはじめ、選択、ラジオボタンなどさまざまのものがあって、onClickのようなイベントハンドラとともに、ユーザとからの入力を受け取り、または処理結果を返す仕組みで、ユーザとの対話を可能にするものです。formやtext、button onClickは、body部の中に、上記のよう形式で記述します。

JavaScriptでは、フォームはdocument オブジェクトのプロバティであり、同時にフォーム・オブジェクトであるとみます。使うときはインスタンス(実例)で、document.myform のようにします。myformとは、formタグの中で、name属性 で指定しています。textはその下にあるオブジェクトでやはり、インスタンス、同じく、textにかかわるタグの中で、name属性で指定したものを使います。上記ではtext2としており、document.myform.text2.value のように階層構造で表示します。valueはtextオブジェクトのプロパティで、textボックスの値を取得したり、代入したりします。この例では代入です。

2. サイコロの目(乱数の精度)

乱数発生のMath.random()は、0から1までなので、6倍して、0から6までとし、サイコロの目まがいにしてみます。その点は偶然にも6倍するところまで、おみくじの例に同じです。

結果的に、乱数のばらつき具合を見ることにもなります。1万回の試行では、今ひとつですが、10万回なら、かなりばらつきがいいようです。

発生させたい乱数の大きさはbody部に書くフォームの中のテキストボックスに書きます。これは、3-1 おみくじの例にはなかったものです。ボタンの中に書くイベントハンドラ(ここではonClick)で、head部に書いた関数に渡します(関数を呼ぶところは、おみくじに同じ)。10000個の乱数を発生させたいとします。テキスト・ボックスから関数には、document.myform2.text1.valueと、フォームの階層構造を反映したオブジェクトとプロパティで、その10000が関数に渡されます。

おみくじでも述べましたが、documentオブジェクトの中のformオブジェクトのtextオブジェクトのプロパティ、valueに入力した値があるというわけです。(下位のオブジェクトは上位のオブジェクトのプロパティ、例えば、textオブジェクトは、上位のformオブジェクトのプロパティのひとつという関係にあります)。

処理結果をテキスト・ボックスに書き出すのは、おみくじ同様、document.myform2.text2.value の形を関数の中で使いますが、サイコロの目は6ケですから、text2からtext7まで6ヶ使っています。発生させたい乱数の数だけ、forで繰り返しますが、発生させた乱数を6倍して整数化したものが、サイコロの目に相当するとして、1だけ加算する配列を振り分けます。

その振り分けは、if.....elseで、できなくはないですが、こういう場合は、switch...case が便利です。

テキスト・ボックスに入力されるデータは文字列です。そこで、後の処理のため、parseInt()ないし、eval()、あるいはNunber()という組み込み関数 で数値に変えます。ここでは、eval()を使ってみました。parseInt()などを探すのに、辞典が役立ちますが、とほほのJavaScriptリファレンス の9も詳しい。

テキスト・ボックスに入れた数は見た目には数値に見えるのですが、文字列なのです。両者はコンピュータの内部でまったく違うコードになります。文字列と数値の違いについては、5章の4のプログラム「文字列を16進コード文字列に変換」で体験してみてください。

4 配列のソートなど

2章の例で、例えば、1000までの和を求めるのに、1000という値をプログラムの中に入れています。これを10000までの和とするには、プログラムを直さないといけない!! テキスト・ボックスに入力させるとどうなるか? それがこの章の主題です。

プログラム例は、配列のソートなど にあり、入力テキストに値を入れて実行してみてください。プログラムそのものは「表示−ソース」 でもいいですし、program-form.txt にもおきました。下記の4つのプログラムを一気に示します。

取り上げる例題は、2で扱ったものもあり(4-1は2-1,4-2は2-4)、フォーム、テキストボックス、ボタン、イベントハンドラ、関数にいては、3に詳しく書きました。ここでは、補足的説明と、それぞれの例題のプログラムで注意すべきこと、特徴的なことのみ記述します。

1. テキスト・ボックスのデータの受け渡し処理(1からnまでの和の例)

BODYタグの部分のフォームの実行ボタンをクリックすると、HEADタグの関数が呼び出されます(関数名はsum()、onClick="sum()" という形。

処理結果をテキスト・ボックスに書き出すのは、関数 function sum() の中で、
  document.myform1.text2.value = sum + " "
としています。右辺は数値を文字列に変換しているものです。その文字列データをtext2のvalueプロパティに代入することで、テキストボックスに書き出します。

2. ソート(乱数を発生させたデータ)

発生させる乱数の数を入力します。その数だけの乱数を1000倍したあと、整数化して、配列に入れます。ソートした配列をそのまま、テキスト・ボックスに書き出すだけです。
なお、ソート前の乱数および2.4で触れた文字列でソートした結果も出しておきます。

3. ソート(配列のデータ)

ソートすべきデータをスペースで区切って、テキスト・ボックスに入れていただきます。そのスペースを頼りに、文字列Stringのメソッドであるsplit(space)で、分割して、それぞれを配列に入れます。後は、前の2の例と同じです。最初の入力の区切りがカンマだったら、split(",") になります。

配列のメソッドsort()を使わない例を自作してみたかったのですが、forとwhileだけの繰り返しでは、私にはちょっときつい。昔、Lispゆずりの強力な再帰用法を持つLogoという言語で、クィック・ソートを勉強したことがあるのですが、実際にやってみましたが、JavaScriptは残念ながら再帰による繰り返しは使えないようでした。なお、2-3のソートは、Javaチュートリアル 第3版(ピアソン・エデュケーション 2001/11)にあったものをJavaScriptに直したものです。

4. スペースで区切られたデータを配列にいれる

splitメソッドを自作してみました。スペースで区切られて、テキスト・ボックスに入力された文字列を1文字ずつ、charAt()で取り出します。それが空白でないなら、char1に文字列結合し、空白なら、そこまでのchar1を配列に入れるという考え方です。
繰り返し回数には、文字列のプロパティであるlengthを使います。

5. historyオブジェクト

プログラム例、配列のソートなど の右上、右下に「戻る」ボタンをつけましたが、これはFORMの中のポタンです。クリックすると、history.back()というブラウザが持つhistoryオブジェクトのメソッドを呼ぶということになっています。formタグは不要のようです。
<INPUT TYPE="button" VALUE="戻る" onClick="history.back()">

次に進むときは、forward() nだけ先に行くなら、go(n)です。ブラウザ自体に「戻る」などのボタンがあるし、アンカータグ A href="リンク先" でもできるし、それほど意義のあるものでもないですが、便利ではあり、JavaScriptの応用のひとつとしてのせておきます。

5 16進数変換・文字コード

3章、4章と内容的には同じです。テキスト・ボックスへの入出力には、document.myform1.text1.valueのような形で使うこと、onClickというイベント・ハンドラのひとつを使って関数を呼び出すこと、document.write()、new演算子に続き、Math.max()、Math.floor()、Math.random()、data2.sort()などのオブジックトとメソッド、parseInt()ないし、eval()という組み込み関数、Stringのメソッドであるsplit()、charAt()も見ましたが、さらに、いくつかの新たなメソッドないしプロパティが出てきます。

プログラム例は、16進数変換・文字コード でご覧下さい。下記の5つ(うち2つは、JavaScriptの持つオブジェクト、メソッドを使うと、いかに簡単になるかの例で実質は3つ)のプログラムを一気に示します。 やはり、入力テキストに値を入れて実行してみてください。第3章同様、それぞれのプログラムで注意すべきこと、特徴的なことのみ記述します。

そのプログラムそのものは、program-form2.txt。上記を実行しているときに、「表示−ソース」でもいいです。

1. 16進数変換

第2章5節で2進数変換をやりました。16進数変換の場合には、10進数を16で割った余りを使います。すると、10以上15までの数も余りとして出てきます。これも16進数の場合には、1桁で表示しないといけないので、慣例にしたがって、AからFまでを割り当てます。

bunrui(n)という別関数で10をA,11をB,......,15をFというように変換しています。このときも、switch....caseが便利です。後は、2進数変換と同じ、テキスト・ボックスへの入出力も第3章と同じです。

2. 16進数変換その2

1では、ごつごつとしたプログラムを自作しましたが、実は数値オブジェクトに、toString(radix) というメソッドがあり、あっという間に、16進でも、2進でも、8進でも変換してくれます。

radixはn進数、16進数の場合は、document.myform2.text2.value = nn.toString(16).toUpperCase(); としています。AからFは、小文字で出力されるので、文字列オブジェクトのメソッドである、toUpperCase()を使って大文字に変換します。範列のように、new演算子不要で、単なる数値、単なる文字列が、そのままで数値ないし文字列オブジェクトのインスタンスとして扱われ、それぞれが持つメソッド、プロパティが使えるということです。

3. 16進数を10進数に変換

2とは逆のことをやるのですが、プログラムはまるで違います。
  document.myform3.text1.valueで入力された16進数を文字列としてnnに受け取り、 その文字列の長さ nlen=nn.lengthを 桁の数とみます。

function decimal() {
    …… 
      for (i=0; i<nlen; i++) {
	m=bunrui2(cStr.charAt(i));
      //ある桁をとりあげ、A〜Fなら10〜15に変換
	n=parseInt(m);    //数字に変換
        ans += n * Math.pow(16,(nlen-1-i)); //16のべき乗の和として計算
    }
 …… 
}   

この繰り返しのforですが、具体的に見た方が分かりやすいですね。
 例えば、5AF=5*162+A*161+F*160という16進数を例にして考えます。桁数(nlen)は3、最上位の16のべき乗はそれより1少ないので、n * Math.pow(16,(nlen-1-i))のi=0の場合にあたります。
 Math.pow(16,x)が、16xにあたるMathオブジェクトのべき乗計算のメソッドです。
 次の桁は、iが1の場合にあたり、iの値を変えて同じことをすればいいですね。

5AFをcharAt(i)で1文字ずつ見ていき、それがAとかFなら、bunrui2の関数で10とか15という文字列に変換した後、parseIntで数字にするという手順を踏んで、上記のくり返し処理に入ります。

途中経過を打ち出してみると、上記説明も多少は分かりやすいかもしれません。フォームにtext形式をひとつ追加して(text3)、途中経過累積を書き出します。その部分を上記のfunction decimal() に追加します。少々複雑ですが。

function decimal() {
    …… 
    var keika= "";      //途中経過
    var keikadata= "";  //途中経過累積
    for (i=0; i<nlen; i++) {
    ……
     keikadata += i + " " + cStr.charAt(i) + " " + n + " " + ans + " ";
     keika += keikadata; //途中経過の累積
     }
       ……
     document.myform3.text3.value=keikadata;
     document.getElementById("keika").innerHTML = keikadata;  //DOMの応用例
}

body部に追加(途中経過累積をinnerHTMLにより、ここに書き出す)。
<p>途中経過</p>
<p id="keika2"></p>

16進数 5AFの10進変換の途中経過 は、
i=0 5*16^2=1280 合計= 1280; i=1 A*16^1=160 合計= 1440; i=2 F*16^0=15 合計= 1455;
と出力されます。

なお、document.write()を繰り返しの中にいれればいいように思ったのですが、JavaScriptをbody部に書く場合には使えても、JavaScriptをhead部に書いている場合にはだめなのです。その代わりとなるような機能に、innerHTML というのがあります。body内に書き出す位置をhtmlのタグ、class属性に似た機能を持つid属性で指定します。innerHTMLは、idで指定したhtmlのオブジェクト(DOM=Document Object Model のプロバティのひとつで、idで指定されたタグ内のテキストの代入/取得を行うものです。 同様のものに、タグつきのまま処理するouterHTMLがあります。

DOMについては、JavaScriptの応用1JavaScriptの応用2 で詳述します。

4 16進数10進変換その2

2が16進数変換の1を簡潔にしたように、実は16進数10進もきわめて簡潔に記述ですます。toString()のようなメソッドさえ不要、たったの1行、これ以上はない簡単なものです 。parseInt(document.myform3.text1.value)は、フォーム myform3 のテキストtext1 の文字列入力を数値に変換するものだから、他にはなにもいらないはずです。ただし、入力したものは16進数であることをJavaScriptに教えるために、最初に 0X をつけます。たとえば、5FAの10進数を知りたいなら0X5FA。123なら、0X123。

5. 文字列を16進コード文字列に変換

これは、2章の最初に紹介した「ホームページに今すぐ活かせるJavaScript」のP258そのままのプログラムです。文字列としての数(文字コード)と数値とがいかに違うかを見てください。例えば、1 の文字コードは、16進で31になります。2進に直すと、00110001ですが、実際の数値は、00000001です。

こういうことがあるから、2進、16進変換では、暗黙のうちに文字列に変えたり、テキスト・ボックスの入力データは、parseInt()などで、文字列から数値に変換する必要があるのです。こういうことを視覚的にみせてくれるというので、このプログラムを紹介する次第です。

また、このプログラムは、アルファベット、ひらかな、漢字の文字コードも出ますから、いろいろとやってみてください。

プログラム的には、すでに説明済みの1文字取り出すcharAt()ではなく、ISO_Latin-1の文字コード(「ホームページに今すぐ活かせるJavaScript」P204参照)に変換するcharCodeAt()を使い、それを16進に変換するtoString(16)との組み合わせで使われています。A〜Fは、やはり小文字で出力されるので、toUpperCase()を使って大文字に変換しています。

WEB上には、文字コード表についての情報も豊富です。日本語と文字コード、あるいは Japanese <-> Unicode Mapping Rules などを参照して、文字コード表と対応させながらトライするのも面白いでしょう。

6 Javascript命令・オブジェクト・DOM まとめ

1 Javascript命令(ステートメント)
  for,while,do while,var,if,else,switch,case,break,continue,
  return,this,new,with

2 オブジェクト
  2通りあり、ブラウザソフトが持つオブジェクトとビルトインオブジェクト(組み込み)で、JavaScript
  独自のものとがある。いずれも、クラスの概念までは持たず、Template(ひな型)として機能する。
 ・ブラウザ・オブジェクト
   window,document,history,location,link,anchor,form,image,appletなど。
 ・ビルトイン・オブジェクト
   Date,Array,Math,String,Number,Boolean,Function,Objectなど。

3 メソッド、プロパティの使い方
 newを使って、オブジェクト(テンプレート)からインスタンス・オブジェクトを作り出してから使うものと
 直接、使えるものとがある。
  前者は、新しい配列を作るときに使う、new Array()とするとか、日付けを取得するときの new Date()で
  あり、こうして作り出したインスタンスは、テンプレートに用意されているメソッド やプロパティを使
うことができる。7-1の data2.lengthがその例で、配列の長さを返すArrayのプロパティを使っている。
  後者は、Math.pow(radix,n)やMath.max(x,y)のように、オブジェクト名に続けて使う。ブラウザ・オブジェ
クトはほとんど、こちらのタイプ。
  なお、数値や文字列はnewは使わないが、それ自体が数値(Number)や文字列(String)オブジェクトのインス
タンスであるとみてよい。nn.toString(16)は、数値インスタンスに対して、Numberオブジェクトの16進数に
変換した文字列にするという toStringメソッドを使っている例。nn.charAt(i)は、文字列nnに対して、
Stringオブジェクトの 1文字取り出す charAtメソッドを使った例だし、charCodeAtも同様である。

4 フォームについて
 formはオブジェクトであるが、documentオブジェクトのプロバティとしてその下位にある。
 document.myform.text1.value = s; のように、階層構造をなす下位のオブジェクトを指定し、最後はtext1
オブジェクトのプロパティvalueに、右辺の値を代入するという形をとっている。プロパティとはオブジェク
トの持つ一種の変数であるが、text1はオブジェクトであると同時に、myformのプロパティでもある。
 myform,text1は、それぞれ、form,textオブジェクトを原型に作られたインスタンス・オブジェクト(myform
 とかtext1はname属性で指定している)。

5 リファレンス
  メソッド、プロパティを上手に使うことが必要であるが、どのようなものがあるかは、なんどもふれてき
  た、とほほのJavaScriptリファレンス の4に一覧、10以下に詳細がある。

6  クラスについて
  JavaScriptのオブジェクトには、Javaと違って、クラスという明確な概念は希薄である。関数から、自分
なりのクラスを作成することはできるということで出てくる程度である。
  Javaでは、オブジェクト(テンプレート)はすべてクラスという。次に予定されている
  ECMAScript4(JavaScript2.0) では、多少明確にされるのかもしれない。

7  DOM(Document Object Model)
「Document Object ModelはW3Cが規定したHTML や XML の文書をプログラム言語で処理できるようにした
インターフェイス(API)であり、一例をあげれば、ウェブページ中のスクリプトから getElementsByTagName 関数
が呼ばれたときは、 HTML ウェブページ中のすべての <P> 要素をノードの配列として返す。」(概要)ものとある。
最もよく使われるインターフェイスを列挙すると、
document.getElementById(id)          document.getElementsByTagName(name)
document.createElement(name)         parentNode.appendChild(node)
element.innerHTML                    element.style.left 
element.setAttribute                 element.getAttribute 
element.addEventListener             window._content 
window.onload                        window.dump() 
window.scrollTo() 

最後に
最初,5章として、フォームの選択項目にあるMIDIファイルを選択して、BGMとして鳴らしてみようというものを入れていましたが、JavaScript2の5章とあわせ、MIDIの音楽とJavaScript にまとめ、 そのなかのMIDI1-フォームの選択肢を使う- に移しました。 また、ダイナミックHTML、フォーム入力のチェック、イベントハンドラについての例、オブジェクトとDOMについての説明、及びWeb上の参考資料は、次のJavaScript応用1JavaScript応用2に書きます。

ページ独自カウント