主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JavaScript: 簡単なスクリプト(コード)で理解する「オブジェクト指向」

                
tags: JavaScript
その1 - そもそもオブジェクトとはなんぞ
その2 - "コンストラクタ"を使うと類似オブジェクトを作るのが便利
その3 - "プロトタイプ"を使うとオブジェクト作成が合理的になる
番外編 - クラスの概念に縛られた巷のオブジェクト指向の説明

 はじめて「オブジェクト指向」という言葉をきいて、Wikipediaで意味を調べ、技術系のWebサイトなどにある「何分で分かるオブジェクト指向」などの記事をいくつか読んだが、やけに長いたとえ話が多く、理解が少し難しく感じた。今にして思えば、そのたとえ話もオブジェクト指向を知らない人には難解なものだったと思う。人や犬を表すオブジェクトなんかを初心者に作らせてどうするつもりなんだろか。ゲーム作れるプログラマならそれをゲームに登場させればいいが、基本的な型を覚えてからオブジェクト指向に入ってきたばかりの人には、こんなんどうやって使えばいいのさと困惑を与えかねない。さらにはオブジェクトの概念もろくに説明しないまま、クラスとか継承とかまで説明しちゃってるのもあるし。
 とくにJavaScriptでオブジェクト指向を学ぼうとするのはちょっぴり厳しいように思う。「オブジェクト指向 JavaScript」でググってみてトップ2ページに出てくるのは、ほとんどがクラスベースの他言語を知っている前提で書かれた記事だ。他言語の知識なしにも追いかけられる内容になっているのは、MSDNの記事ぐらい。それでもそもそもの用語の説明は省かれているのできついものがある。

 JavaScriptは近年、その存在感を増してきた。おかげでプログラミングを最初に学ぶための言語の選択肢としても、目的次第ではかなり妥当なところになっていると思う。だから他のクラスベースの言語を経由せずに、JavaScriptでオブジェクト指向を学べるようにする必要がある。クラスのない言語で、これはクラスみたいなものだよ、と言われても知らない人はちんぷんかんぷんだ。
 プログラマならオブジェクト指向のいいところを交えつつ、自分で触れるシンプルなスクリプトで見たほうが納得しやすいんでは、と思ったので自分なりに「オブジェクト指向」というキーワードの説明をJavaScriptベースで展開してみる。変数と関数を使って自分でスクリプトが考えられるようになった人のために。




 オブジェクト指向は、あるページで以下のように説明されている(参考)。
”関連するデータの集合と、それに対する手続き(メソッド)を「オブジェクト」と呼ばれる一つのまとまりとして管理し、その組み合わせによってソフトウェアを構築する”
これがどんなことなのか察しがつかなければ、この定義はここで一旦忘れて問題ない。ただ、クラスって言葉は出てきていないし、新しく聴く言葉もメソッドとオブジェクトぐらいのものだろう。オブジェクト指向ってものがそんなに複雑な概念でないということだ。

 JavaScriptでストップウォッチを作ってみる。まずは初歩的に、変数と関数で構成する。現在時刻を得るために"Date.now()"を使う。
var time = null;

function start()
{
time = Date.now();
}

function getCurrentTime()
{
var diff = null;
if (time)
{
diff = (Date.now() - time) / 1000.0;
}
return diff;
}

function stop()
{
time = null;
}

使用変数: time
使用関数: start, getCurrentTime, stop
デモ

 できた。関数startを実行した後で関数getCurrentTimeを実行すれば経過時間が得られるし、関数stopを実行することで時間計測は終了する。しかし計測開始時間を記録しておくために、グローバル変数を一つ使っている。このストップウォッチ機能が必要なページに機能をもっと付加したくてスクリプトを追加するとき、このグローバル変数に想定外の干渉が起こらないように気を払わなければらならくなる。

 ここで「オブジェクト」を使うことを考えてみる。オブジェクトとは、任意のオブジェクト名の下に変数や関数をまとめることができるものだ。JavaScriptを学んでいれば「連想配列」としてオブジェクトを学んだかもしれない。オブジェクトには任意の名前を付けることができて、その名前の下に変数も関数も入れられるということが重要なところ。

// オブジェクトの宣言(名前はobj)
var obj = {};

// オブジェクトobjに変数を追加する
obj.hensuu1 = 0;
obj.hensuu2 = true;
obj.hensuu3 = "foo";

// オブジェクトobjに関数を追加する
obj.kansuu1 = function(){return 0;};
obj.kansuu2 = function()
{
var num = obj.hensuu1 + 3;
return num;
};

// オブジェクトobjに入れられた各変数を呼び出し、アラートウィンドウで表示
alert(obj.hensuu1);
alert(obj.hensuu2);
alert(obj.hensuu3);

// オブジェクトobjに入れられた各関数を実行し、返り値をアラートウィンドウで表示
alert( obj.kansuu1() );
alert( obj.kansuu2() );

 上記のようにオブジェクトには変数も関数も入れられる。オブジェクトに入れられた変数のことをプロパティと呼び、オブジェクトに入れられた関数のことをメソッドと呼ぶ。この呼び名はドキュメントを読む上では重要。

 オブジェクトに変数や関数を入れられることがわかった。ではさきほど書いたストップウォッチのスクリプトを、オブジェクトを使って書き換えてみる。
var stopWatch = {};

stopWatch.time = null;

stopWatch.start = function()
{
stopWatch.time = Date.now();
};

stopWatch.getCurrentTime = function()
{
var diff = null;
if (stopWatch.time)
{
diff = (Date.now() - stopWatch.time) / 1000.0;
}
return diff;
};

stopWatch.stop = function()
{
stopWatch.time = null;
};

使用変数: stopWatch.time
使用関数: stopWatch.start, stopWatch.getCurrentTime, stopWatch.stop
デモ

 まず変数stopWatchを空のオブジェクトとして宣言する。続いてオブジェクトstopWatchに変数timeをプロパティとして追加。さらにオブジェクトstopWatchに関数start, getCurrentTime, stopをメソッドとして追加。ストップウォッチ機能を構成するための変数や関数が"stopWatch.time"や"stopWatch.start()"というふうになった。"stopWatch."という名前を頭につけなければ変数timeや関数startなどにアクセスできなくなった。これは変数名や関数名の重複が起こる確率がガクッと下がったことになる。
 オブジェクトなしで書いたスクリプトだとストップウォッチの計測開始を"start()"と書いていた。この一文だけを見ても、なにがスタートするか定かではない。オブジェクト適用後のスクリプトでは、関数startは"stopWatch.start()"と書かなければ呼べなくなったが、これを見れば、ストップウォッチがスタートするということが明らかである。今回のようなコンパクトなスクリプトではオブジェクト指向を導入する恩恵はまだうすいが、実装したい仕様が増えスクリプトがそれに伴って肥大化したときには、可読性の向上などが期待できる。
 変数もオブジェクトstopWatchが管理していて、オブジェクトの外の変数を利用していないし、メソッドの実行時にも引数を必要としていない。ただオブジェクトに計測開始、経過時間取得、計測停止の命令を出すだけで、オブジェクトである自分自身の持っている変数を参照してストップウォッチとしての仕事をしている。

 最初に書いたスクリプトではただ変数や関数を羅列して書いただけだったので、それぞれをパッと見ただけでは、これなにに使うんだろと思うはずだ。オブジェクトを使って書いたスクリプトでは変数や関数をオブジェクトの下に入れた。だからそのオブジェクトに関連する変数や関数であることがわかりやすくなった。こんなように、作りたいある機能があって、その機能のために必要な変数と関数をオブジェクトの下にまとめる。それがオブジェクト指向の根本的な考え。クラスかプロトタイプか、継承がどうのというのはこの先の話。オブジェクト指向というからには中核になるのはオブジェクトであって、クラスやプロトタイプではない。まずはオブジェクトがどんなもので、どう使うかってことが重要。
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。