第12話:型、オブジェクト、クラス

第1部 JavaScriptプログラミングの基本

目次

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ

マンガ台詞

【1Page】
アイコン先生:さて この数週間
    プログラムの 基本について 説明していた
    今回がその仕上げとなる
    今日の説明が 終われば プログラム脳が 出来上がるぞ
アイコン麗:プログラム脳って なんだか嫌だわ
アイコン遊:私たち 洗脳されて いたの!
アイコン守:僕もちょっと 嫌かも
アイコン先生:えー 不評だな……
【2Page】
アイコン先生:さて これまでに 『数値変数』と 『文字列変数』が あると説明した
    この変数の違いは『型』と言い 『typeof』関数で 調べられる
        var no = 0;         // 『数値変数』を初期化
        var str = "文字列";    // 『文字列変数』を初期化
        // 『typeof』関数で、変数の『型』を調べる
        alert(typeof(no));  // 『number』(数)と表示
        alert(typeof(str)); // 『string』(文字)と表示
    実は この2つ以外にも 変数の『型』は存在する
アイコン遊:おのれ 騙したな!
アイコン先生:騙して いないよ
アイコン先生:まず1つめは 真偽の値を表す変数
    これは『boolean』 という型で 『真』か『偽』が 格納される
        // 真偽の判定結果で変数を初期化
        var bool = (1 > 0);
        alert(typeof(bool));
        // 『boolean』(真偽)と表示

        // 真を表す『true』で変数を初期化
        var bool = true;
        alert(typeof(bool));
        // 『boolean』(真偽)と表示
【3Page】
アイコン先生:2つめは 『オブジェクト』型の変数
    3つめは 『function』型の変数だ
アイコン遊:『function』型?
アイコン先生:『function』型は ちょっと置いておいて 『オブジェクト』型を説明する
    実はJavaScriptでは この『オブジェクト』型が 非常に重要なんだ
アイコン遊:オブジェクト? ちょっと前に 出てきたわね
アイコン麗:英語で『物』って 意味ですよね
アイコン先生:そうだ
アイコン遊:(麗に)この優等生が!
【4Page】
アイコン先生:え~~
    『オブジェクト』型変数は
    物というよりは 値や関数が入った 箱だと思った方がよい
        オブジェクト
            値
            :
            関数
            :
    これらの値や関数は 『オブジェクト.要素名』
    『オブジェクト.要素名()』 と書いて利用できる
        object.variable;
        object.function();
アイコン遊:あれ?
    その書き方 どこかで見た 覚えがある
アイコン先生:こうだろう?
        document.title;
        document.write("");
アイコン遊:そう それ!
【5Page】
アイコン先生:実はこれまで 利用してきたけど
    ちょっと難しいので 説明してなかったんだ
アイコン遊:ぶー 騙された~
アイコン先生:こういった 『オブジェクト』内にある
    『値』を『プロパティ』
    『関数』を『メソッド』と呼んだりする
    『document』は
    Webページに最初から 用意されている
    『オブジェクト』の ひとつなんだ
    なので『for in』文で 『document』の中身を 調べることもできる
        var str = "";
        for (var key in document) {
            str += "キーが " + key
                + " : 型が " + typeof(document[key])
                + " : 値が " + document[key]
                + "<br>"; // 改行タグ
        }
        document.write(str);
    『キーが namespaces : 型が object : 値が [object]
    キーが parentNode : 型が object : 値が null
    キーが nodeType : 型が number : 値が 9
    キーが onbeforeeditfocus : 型が object : 値が null
    キーが bgColor : 型が string : 値が #ffffff
    キーが oncontextmenu : 型が object : 値が null
    キーが onrowexit : 型が object : 値が null
    キーが embeds : 型が object : 値が [object]
    キーが scripts : 型が object : 値が [object]
    キーが onactivate : 型が object : 値が null
    :』と表示
【6Page】
アイコンアイコンアイコン3人:おおっ!
アイコン先生:すごいだろ
    また JavaScriptでは 文字列や配列なども 『オブジェクト』の 一種なんだ
        注:『typeof』では 文字列は『string』 配列は『object』
        関数は『function』と表示される
アイコン麗:そういえば 文字列変数や配列には 長さを表す『.length』 などがありましたね
アイコン先生:そうだ 
    同じように 関数も変数 として扱える
    これが 後回しにした 『function』型だ
        // 関数を作成
        var func = function () {
            alert("関数を変数にしたよ!");
        };

        // 関数を実行
        func();

        // 配列に関数を入れて実行
        var arr = new Array(1);
        arr[0] = func;
        arr[0]();

        // オブジェクトの要素に関数を入れて実行
        var obj = new Object();
        obj.func = func;
        obj.func();
    3つとも きちんとダイアログが表示される
【7Page】
アイコン遊:よく分からないけど すごいのは分かったわ
アイコン守:あの 先生 『function』のあとに 名前がないんですが?
        var func = function () {
アイコン先生:よく気付いたな こういった名前のない 関数のことを 『無名関数』と言う
    また これまで説明した 『オブジェクト』の 仕組みを利用すれば
    値と関数をまとめた 『クラス』と呼ばれる ものを作れる
        // 生徒クラスを作成
        var Seito = function(namae, tensuu) {
            this.namae  = namae || "???";
            this.tensuu = tensuu || 0;
            this.show = function() {
                window.alert("名前 : " + this.namae
                    + " / 点数 : " + this.tensuu);
            };
        };

        // 生徒クラスを使って『生徒 遊』変数を作成
        var sYuu = new Seito("遊", 3);
        alert(sYuu.namae + " " + sYuu.tensuu);
        sYuu.show();

        // 生徒クラスを使って『生徒 不明』変数を作成
        var sHumei = new Seito();
        sHumei.show();
    『遊 3
    名前 : 遊 / 点数 : 3
    名前 : ??? / 点数 : 0』と表示
【8Page】
アイコン先生:どうだ すごいだろう!
アイコンアイコンアイコン3人:ぽかーん
アイコン遊:うう~っ 難しすぎて 頭がパンクする
アイコン先生:あー すまなかった お前たちには 早すぎた
    お詫びに ジュースを 買ってやろう
アイコン遊:チューチュー
    ぱー
アイコン麗:庶民ね 簡単に買収されて
アイコン先生:今回は かなり高度な 話だったな
    反省して 次回は簡単な 話にしよう

説明

この章では、『型』『オブジェクト』『クラス』について学びます。この3つは、JavaScriptというプログラミング言語の根幹に関わる部分です。内容的には少し難しいですが、ここまで全て分かればJavaScriptについて、非常に深く理解したことになります。そして、JavaScriptの基本はマスターしたことになります。

それでは、『型』『オブジェクト』『クラス』について、順に説明していきます。

『型』

『typeof』関数

これまで変数には『数値変数』と『文字列変数』があると説明してきました。実は、JavaScriptには、この2つ以外にも変数の種類が存在します。この変数の種類のことを『型』と言います。

変数の『型』は、『typeof』関数を使って調べることができます。

var no = 0;            // 『数値変数』を初期化
var str = "文字列";    // 『文字列変数』を初期化

// 『typeof』関数で、変数の『型』を調べる
alert(typeof(no));     // 『number』(数)と表示
alert(typeof(str));    // 『string』(文字)と表示

『boolean』型の変数

『boolean』型は、『真偽』を格納する変数です。これまで『if』などで利用していた『真偽の判定結果』を、『変数』として利用できます。また、『true』(真)『false』(偽)という値で初期化することで、『真の値』『偽の値』を持った変数を作ることもできます。

var bool = (1 > 0);     // 真偽の判定結果で変数を初期化
alert(typeof(bool));    // 『boolean』(真偽)と表示
var bool = true;        // 真を表す『true』で変数を初期化
alert(typeof(bool));    // 『boolean』(真偽)と表示

『オブジェクト』型、『function』型の変数

変数の型には『オブジェクト(object)』型、『function』型というものも存在します。この『オブジェクト』型は、JavaScriptでは特に重要です。

以下、『オブジェクト』型の変数は『オブジェクト』の項で、『function』型の変数は『クラス』の項で詳しく解説します。

参考

『オブジェクト』

既に『オブジェクト』については触れています。要素名を文字列で指定して、値を格納していました。このように、『オブジェクト』型の変数は、内部に値を格納しています。ここでは、内部の値が関数かどうかで区別してみます。

『オブジェクト』型変数内の値は『オブジェクト.要素名』、関数は『オブジェクト.要素名()』として利用できます。

object.variable;      // 『オブジェクト』型変数内の値を利用
object.function();    // 『オブジェクト』型変数内の関数を利用

下記の『document』は、Webページ内でJavaScripを利用する際に、最初から用意されているオブジェクトです。他にも、『window』などのオブジェクトが、用意されています。これらの使い方は、もっと先の章で紹介します。

document.title;         // 『document』オブジェクトの『title』変数
document.write("");     // 『document』オブジェクトの『write』関数

また、既に説明したように、オブジェクトの要素には、『オブジェクト["要素名"]』『オブジェクト.要素名』の2つの方法でアクセスできます。どちらの方法でも、同じ値を参照できます。

『プロパティ』と『メソッド』

『オブジェクト』の要素のことを『プロパティ』と呼びます。『プロパティ』の中でも、関数は特別に『メソッド』と呼びます。今後、説明に多く出てきますので、覚えておいてください。

『クラス』

『function』型の変数

変数の『型』には『function』型と呼ばれるものがあります。これは、『関数』を変数として格納したものです。JavaScriptでは、『関数』も数値や文字列と同じように、変数に入れて利用できます。

以下、『関数』を変数に入れて利用する例を示します。

// 関数を作成
var func = function () {
    alert("関数を変数にしたよ!");
};

// 関数を実行
func();       // 変数の後に『()』を付けて実行
// 配列に関数を入れて実行
var arr = new Array(1);
arr[0] = func;
arr[0]\();    // 配列の要素の後に『()』を付けて実行
// オブジェクトの要素に関数を入れて実行
var obj = new Object();
obj.func = func;
obj.func();   // オブジェクトの要素の後に『()』を付けて実行

3種類示しましたが、いずれもきちんとダイアログが表示されます。

『無名関数』

『function () {~}』のように、『function』の後に名前がない関数のことを『無名関数』と呼びます(『匿名関数』と呼ぶこともあります)。

JavaScriptでは、ある程度以上に高度なプログラムを書き始めると、この『無名関数』を多用するようになります。そのため、こういった「名前のない関数」があるということを覚えておいてください。

この『無名関数』については、もっと先の章で詳しく説明します。

『クラス』

それでは次に、『function』型の変数を利用して、『クラス』と呼ばれるものを作ります。『クラス』は、『共通の変数や関数を格納した変数』を作るための仕組みです。

たとえば『生徒』についての情報を扱いたいとします。『生徒』には『名前』や『テストの点数』といった情報を格納することにします。また、『生徒』の情報をいつでも簡単に呼び出せる方法も用意しておきます。

こういった共通した機能を持たせるために、以下のような構造の変数を作ります。

 『生徒』変数
   ・『名前』文字列
   ・『テストの点数』数値
   ・『情報を表示する』関数

こういった変数を『オブジェクト』型変数を使って作ると、以下のようになります。

var Seito = new Array();
Seito.namae = "遊";
Seito.tensuu = 3;
Seito.show = function() {
    window.alert("名前 : " + this.namae + " / 点数 : " + this.tensuu);
};

これで1人分の変数を作ることができました。しかし、このやり方で30人分の変数を作ろうとすると大変です。この変数は、『名前』変数も『テストの点数』変数も『情報を表示する』関数も共通しているので、一度だけ宣言して再利用したいところです。

そういった場合には『function』型変数を使って、『クラス』と呼ばれるものを作ります。以下、『生徒』クラスのサンプルです。

// 生徒クラスを作成
var Seito = function(namae, tensuu) {
    this.namae  = namae || "???";
    this.tensuu = tensuu || 0;
    this.show = function() {
        window.alert("名前 : " + this.namae
            + " / 点数 : " + this.tensuu);
    };
};

『this』という文字の意味は、この章の後半で詳しく説明します。ここでは『クラス』自体を現すオブジェクトだと思っていてください。

上記は、『Seito』という『function』型の変数を作るプログラムです。この『Seito』変数内には、あらかじめ『this.namae』『this.tensuu』『this.show』といった変数や関数が用意されています。そして、関数の『引数』として『namae』『tensuu』が設定されています。

次に、この『Seito』関数を利用して、『生徒 遊』変数を作成します。

// 生徒クラスを使って『生徒 遊』変数を作成
var sYuu = new Seito("遊", 3);
alert(sYuu.namae + " " + sYuu.tensuu);
sYuu.show();

『var sYuu = new Seito("遊", 3);』という部分が最も重要な部分です。『new Seito()』とすることで、新しい『Seito』を作成して、『sYuu』変数に格納しています。

この際に、引数として『遊』『3』という値を設定しています。『Seito』クラスでは、引数を元にして、内部の『this.namae』『this.tensuu』の値を書き換えます。その結果『sYuu.namae』(『sYuu』内の『this.namae』)が『遊』という値になり、『sYuu.tensuu』(『sYuu』内の『this.tensuu』)が『3』という値になった状態で、『sYuu』変数が作成されます。

新しくできた変数『sYuu』を利用した『alert(sYuu.namae + " " + sYuu.tensuu);』の行は、『遊 3』と表示されます。また、『sYuu.show();』の行は『名前 : 遊 / 点数 : 3』と表示されます。

『クラス』のこの仕組みを利用すれば、以下のように手軽に生徒の情報と命令を格納した変数を作れます。

var sMamoru = new Seito("守", 95);
var sRei    = new Seito("麗", 92);

こういった仕組みは、プログラムを書き始めても、すぐには利用しないと思います。しかし、いずれ必要になり、そして重要な役目を果たすようになります。初めてJavaScriptを学ぶ人には少し早いかもしれませんが、覚えておけばいずれ役に立ちます。

(『prototype』を利用したクラスの作成は、初心者には難し過ぎると思うために、ここでは説明を割愛します。ある程度プログラムに慣れてから、チャレンジするとよいでしょう)

『特別な値』

今回は『boolean』型が出てきました。この『真』『偽』を表すのは、『true』『false』という特別な値です。

この2種類以外にも、JavaScriptには、いくつかの特別な値が存在します。よく使うものを、以下にまとめておきます。

表記 意味 説明
true boolean型
false boolean型
null 値なし 変数の中身が空であることを示す
undefined 未定義 オブジェクトの『存在しないプロパティ』などにアクセスした際に戻る値
NaN 数値でない 計算式に文字列が紛れ込んでいた際などに戻る値
Infinity 無限 計算結果が極端に大きな場合に戻る値

『オブジェクト指向』

JavaScript言語は、『オブジェクト指向』と呼ばれるプログラミング言語です。

変数は『オブジェクト』と呼ばれる物として扱われ、その『オブジェクト』の値や関数(プロパティやメソッド)も、また『オブジェクト』として扱えます。これらのオブジェクトは『.』(ドット)で連結して、下の階層へとたどれます。

これまで出てきた『document』は、表記が省略されていますが『window.document』という、『window』オブジェクト内のオブジェクトです。そのため、『write()』という命令は、正式には『window.document.write()』となります。

こういった仕組みになっていることを頭の片隅に置いておくと、JavaScriptは理解しやすくなります。

すぐに分からなくても、プログラムを書いているうちに「あっ!」と気付くことがありますので、覚えておくとよいです。

『this』

『this』とは?

クラスを作る際に、『this』という、これまで説明していない謎の変数が出てきました。

この『this』は、オブジェクト自身を表す特殊な変数です。

といっても『オブジェクト自身』なんて、何のことやらと思うでしょう。

少し難しい説明になるので、「まだ自分は初心者だ」と思う方は、以下は読み飛ばしてください。

JavaScriptは、オブジェクト指向の言語です。そして、全ての変数はオブジェクトとして、成り立っています。そして、このオブジェクトは、何らかのオブジェクトのプロパティやメソッドになっています。

 親オブジェクト
     ┣ 子オブジェクト
     ┃    ┣ 孫オブジェクト
     ┃    ┗ 孫オブジェクト
     ┗ 子オブジェクト
           ┗ 孫オブジェクト

この構造は、JavaScriptの文法的に、『.』(ドット)を使用して書くと、以下のようになります。

親オブジェクト.子オブジェクト.孫オブジェクト

さてここで、『オブジェクト』の頭に『this.』と付けてみます。

this.オブジェクト

何となく分かってきたのではないかと思います。『this』は、そのオブジェクトにとって、親っぽい何かのようです。

関数の外であれば、この『this』は、『window』を表しています。これまでよく利用してきた『alert()』関数は、正式には『window.alert()』です。この『alert()』関数を、『window』の代わりに『this』を頭に付けて実行してみます。

window.alert("");   // 正しく動作する
this.alert("");     // 『this』でも正しく動作する

『this.alert("")』は、正しく動作します。

関数内の『this』

次は関数内の『this』です。関数内であれば、『this』は、関数が呼び出された際に、その関数が格納されていたオブジェクトを表しています。

以下、先ほど書いたコードを元に説明します。

// 生徒クラスを作成
var Seito = function(namae, tensuu) {
    this.namae  = namae || "???";
    this.tensuu = tensuu || 0;
    this.show = function() {
        alert("名前 : " + this.namae
            + " / 点数 : " + this.tensuu);
    };
}

// 生徒クラスを使って『生徒 遊』変数を作成
var sYuu = new Seito("遊", 3);
sYuu.show();

『var sYuu = new Seito("遊", 3);』という行で、新しいオブジェクト『sYuu』を作成しています。

そして次の行の『sYuu.show();』で、『sYuu』オブジェクト内の『show』メソッドを呼び出しています。

『sYuu』の中身は、『new』で初期化された時に、以下のようになっています。

sYuu
   .namae = "遊";
   .tensuu = 3;
   .show = function() {
           window.alert("名前 : " + this.namae + " / 点数 : " + this.tensuu);
       };

『sYuu.show』メソッドが呼び出され時の『this』は、『show』が格納されている『sYuu』というオブジェクトを指しています。

そのため『this.namae』は、『sYuu.namae』の値になり、『this.tensuu』は、『sYuu.tensuu』の値になります。

おまけ

参考までに、上記のプログラムは、以下のように書いても同じように動作します。

// 生徒クラスを使って『生徒 遊』変数を作成
var sYuu = new Seito("遊", 3);
sYuu.show();

// 生徒クラスを作成
function Seito (namae, tensuu) {
    this.namae  = namae || "???";
    this.tensuu = tensuu || 0;
    this.show = function() {
        window.alert("名前 : " + this.namae
            + " / 点数 : " + this.tensuu);
    };
}

関数を『new』で呼ぶと、その関数がオブジェクトとして作成されて、変数に代入されます。

サンプルの入手

以下は、今回出てきたサンプルです。

ZIPでまとめてダウンロード (右クリックから保存してください)

sample1.html』(数値、文字列型)を表示

sample2.html』(boolean型)を表示

sample3.html』(『document』の内部を探る)を表示

sample4.html』(関数を変数として扱う)を表示

sample5.html』(生徒クラス)を表示

sample5b.html』(生徒クラス 書き方違い)を表示

プログラムの中身を見たい場合は、それぞれのHTMLファイルをブラウザで開いたあと、右クリックをして『ソースの表示』を選択してください。

メモ帳で、ファイルの中身を見ることができます。