![]() |
連載:Ajax時代のJavaScriptプログラミング再入門第4回 JavaScriptでオブジェクト指向プログラミング山田 祥寛(http://www.wings.msn.to/)2007/09/25 |
|
|
Back Issue |
||||||
|
JavaScriptが、いま注目を浴びている。
JavaScriptがこれだけの注目を浴びた理由の1つとして、Ajax技術の登場とも相まって、JavaScriptに対する確かな理解の必要性が高まったという事情は否定できない。しかし、それだけでは説明できない急速な注目の理由として、もう1つ、JavaScriptという言語そのものが持つユニークさが開発者の目を引いたという点は看過できないだろう。
もっとも、このユニークさは同時に、多くの開発者が感じているJavaScriptに対する苦手意識と同義でもある。これまでVisual BasicやC#、Javaといった言語でオブジェクト指向構文になじんできた開発者にとって、JavaScriptのオブジェクト指向構文はいかにも奇異なものに映るのだ。ようやくクラスという概念を理解した開発者が、JavaScriptという言語の背後にたびたび見え隠れする「プロトタイプ・ベースのオブジェクト指向」というキーワードに、そもそもの敬遠感を抱いているという事情もあるだろう。
しかし、JavaScriptにおける「プロトタイプ・ベースのオブジェクト指向」は何ら目新しい概念ではない。ごくごく単純化していってしまえば、プロトタイプとは「より縛りの弱いクラス」のようなものと思っていただければよいだろう。
連載最終回となる今回は、JavaScriptで本格的なプログラミングを行うのに欠かせない――そして、JavaScriptに対する苦手意識の根幹でもある(と思われる)「プロトタイプ・ベースのオブジェクト指向」構文について解説する。
なお、本論に入るに当たって、1点のみ注意していただきたい点がある。第1回でも述べたように、JavaScriptでは厳密な意味でのクラスという概念は存在しない。しかし、本稿を読まれている読者の多くはクラス・ベースのオブジェクト指向構文になじんでいると思われることから、ここではJavaScriptにおいて「クラス的な役割を持つ存在」を、便宜上、「クラス」と呼ぶものとする。ご了承いただきたい。
JavaScriptにおける“クラス”の定義
JavaScriptにおけるオブジェクト指向構文について理解するには、抽象的な解説を重ねるよりも、まずは具体的なクラスを実際に作成してみた方が話が早いだろう。以下は、JavaScriptで中身を持たない、最も単純なクラスを定義した例だ。
| |
| リスト1 JavaScriptにおける最もシンプルなクラスの例 |
変数Animalに対して、空の関数リテラルを代入しているだけのコードだ。「これがクラス?」と思われた方もいるかもしれないが、そのとおり、これがJavaScriptにおけるクラスなのである。れっきとしたクラスである証拠に、
|
と、クラス・ベースのオブジェクト指向構文でもおなじみのnew演算子を利用して、実際にインスタンス化を行ってみると、確かに正しく(エラーなども出ずに)実行できることが確認できる。ここではまず、
JavaScriptでは関数オブジェクトにクラスとしての役割を与えている
という点を覚えておこう。
■コンストラクタとプロパティ
コンストラクタとは、オブジェクトを生成する際に自動的に呼び出される関数(メソッド)のこと。クラス・ベースのオブジェクト指向構文を少しでもかじったことのある方ならば、これはごく耳になじんだキーワードの1つであるはずだ。
リスト1で記述したAnimal関数は、new演算子によって呼び出され、オブジェクトを生成するという意味で、厳密には「クラス」そのものというよりも「コンストラクタ」と呼ぶのがより正しいだろう。
コードを見ても分かるように、JavaScriptにおいては、コンストラクタと(普通の)関数との間に本質的な違いはない。関数として呼び出すのか、それともnew演算子によって呼び出すかによって、関数の振る舞いが変わるわけである。もっとも、(構文規則ではないが)実際のコードで、通常の関数とコンストラクタとが区別できないのは不便であるので、一般的にはコンストラクタ(クラス)名は大文字で始めるのが好ましい。
さて、先ほどのリスト1では空のコンストラクタを定義したわけであるが、通常、コンストラクタの中では生成するオブジェクトを初期化するためのコードを記述するのが一般的だ。具体的には、オブジェクト共通で利用するプロパティ(メンバ変数)などを定義するのがコンストラクタの役割なのである。
以下は、リスト1で作成したAnimalクラスにname/sexプロパティを追加した例だ。
| |
| リスト2 Animalクラスにname/sexプロパティを追加したコード |
ここで注目していただきたいのは、コンストラクタの中のthisキーワードだ。コンストラクタとして関数オブジェクトを呼び出した場合、thisキーワードは新たに生成されるオブジェクトを表すことになる。そして、
|
のように記述することで、オブジェクトにプロパティを追加することができるというわけだ。実際、リスト2の例でも、コンストラクタで設定されたname/sexプロパティが、作成したオブジェクトから正しく参照できることが確認できるはずだ。
[注意]コンストラクタに戻り値は不要 もう1点、コンストラクタを定義する場合のささやかな注意点がある。というのも、コンストラクタでは「戻り値を返す必要がない」という点だ。クラス・ベースのオブジェクト指向構文に慣れていればごく当たり前のポイントではあるが、プロトタイプ・ベースのオブジェクト指向構文でもこの点は同様であるので、あらためて注意しておきたい。コンストラクタ関数の役割は、あくまでこれから生成するオブジェクトの初期化を行うことであって、オブジェクトそのものを返すことではない。 |
■メソッド − コンストラクタによる定義 −
いまさらいうまでもなく、オブジェクトの構成は大きく「データ」と「手続き」とに分類できる。先ほどは、プロパティ(メンバ変数)を定義することでオブジェクトの「データ」を定義したので、当然の流れとして、次は「手続き」の部分――「メソッド(メンバ関数)」を定義してみることにしよう。
以下は、先ほどのAnimalクラスにtoStringという名前でメソッドを追加した例だ。
| |
| リスト3 AnimalクラスにtoStringメソッドを追加した例 |
JavaScriptには厳密な意味でのメソッドという概念はない。このリスト3を見ても分かるように、「値として関数オブジェクトが渡されたプロパティがメソッドと見なされる」わけだ。ここではtoStringという名前のプロパティに匿名関数を引き渡すことで、toStringというメソッドを追加したことになる。
果たして、toStringメソッドを実行してみると、確かに「トクジロウ オス」というメッセージが返されることが確認できるはずだ。
■メソッド − インスタンスへの追加 −
もっとも、JavaScriptではメソッドをあらかじめコンストラクタで定義できるばかりではない。インスタンス化されたオブジェクトに対しても、後からメンバを追加できるのがJavaScriptの特徴だ(これをJavaScriptの「動的性質」と呼ぶ)。
そのJavaScriptの動的性質を利用することで、先ほどのリスト3は以下のように書き換えることも可能だ。
| |
| リスト4 インスタンスに対してメソッドを追加した例 |
先ほど同様、toStringメソッドが正しく動作していることが確認できるはずだ。ただし、インスタンスに対して動的にメソッドを追加した場合には、注意も必要だ。
以下に、Animalクラスに対するインスタンスを2つ登場させた例を見てみよう。
| |
| リスト5 Animalクラスに対してインスタンスを複数生成した例 |
インスタンスanim2からtoStringメソッドを呼び出そうとした時点で、エラーが発生することが確認できる。Internet Explorerでは、恐らく「オブジェクトでサポートされていないプロパティまたはメソッドです。」というエラーメッセージが出力されるはずだ。
このことから、インスタンスへのメソッドの追加はあくまでインスタンス(ここではanim)への追加であって、「大本であるクラスへの追加ではない」ことが理解できる。つまり、クラス・ベースのオブジェクト指向言語においては、あるクラスを基に作成されたインスタンスは必ず同じメンバを持つはずであるが、JavaScriptでは同一の“クラス”を基に作成されたインスタンスでも異なるメンバを持つ可能性がある、ということなのである。これが、先ほどプロトタイプ・ベースのオブジェクト指向が、クラス・ベースのそれよりも「縛りが弱い」と述べた理由でもある*1。
| *1 ちなみに、ここではメンバを追加する例について述べたが、インスタンス、あるいはコンストラクタ経由で追加したメンバはdelete演算子(後述)で削除することも可能だ。 |
いずれにせよ、ここでは、
インスタンスに追加したメンバは、
(オブジェクト共通ではなく)そのインスタンスのみで有効である
という点を押さえておこう。
| INDEX | ||
| Ajax時代のJavaScriptプログラミング再入門 | ||
| 第4回 JavaScriptでオブジェクト指向プログラミング | ||
| 1.JavaScriptにおける“クラス”の定義 | ||
| 2.プロトタイプ・ベースのオブジェクト指向 | ||
| 3.プロトタイプ・チェーン − JavaScriptの継承機構 − | ||
| 4.[コラム]オブジェクトと連想配列 | ||
| 「Ajax時代のJavaScriptプログラミング再入門」 |
ホワイトペーパー(TechTargetジャパン)
- .NET TIPS - .NET開発のテクニックとヒント集 - (2010/3/18)
− GridViewコントロールを階層表示させるには?
− Windowsフォームのボタンに画像を表示するには?
− C#でnullチェックを簡潔に行うには? - Chapter15:LINQとクエリ式 (2010/3/17)
C# 3.0の目玉機能であるLINQについて、さまざまな記述例を交えながら徹底解説。書籍『[完全版]究極のC#プログラミング』より転載 - VBラムダ式 基礎文法最速マスター (2010/3/16)
今度はVB。ラムダ式の基礎文法を、短い説明と簡単なコードでまとめる。「ラムダ式、どう書くんだっけ?」という場合の簡易リファレンスとして活用できる - ASP.NET MVC 2がリリース (2010/3/15)
ASP.NET MVC 2の正式版(VS 2008のASP.NET 3.5向け、VS 2010には標準で含まれる予定)のリリースについてのお知らせ
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
| 「いつかは壊れるサーバ」そんな故障に 迅速で安価に手軽に対応する方法とは? New! |
| 「特権ユーザー」の事件を防げ! 万能権限を持つユーザーの管理方法とは? New! |
| 仮想環境の構築とデータ保護の特効薬?! 実績と信頼性の高いパッケージで安心運用 |
| 仮想環境のバックアップもこれまでどおり 「まるごと取ってまるごと戻す」簡単運用 |
| おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |
| その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |
| 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |
| 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |
- - PR -
お勧め求人情報

**先週の人気講座ランキング**
〜CCNA編〜
| ◆ | TomcatやJBossなどAPサーバ環境に関する 情報を集約! “業務”用APサーバ大百科 New! |
| ◆ | 一気に解説! 最新のクラスタストレージ 「RAIDを超えたストレージ基準」……など New! |
| ◆ | クラウド的ユーザー体験の変化は脅威か? 仮想化技術を使いこなす運用管理術を紹介 New! |

| ◆ | 上司や部下、部署内メンバーとの情報共有 を“ガラッ”と変えるコラボツールとは? New! |
| ◆ | おばかアプリ選手権、第4弾開催中!! ムダにカッコよくてくだらない作品求ム! |
| ◆ | 社内ファイルサーバを“クラウド”に統合 VPN直結「クラウド型ストレージ」を紹介 |

| ◆ | Twitterのアカウントはなぜ突破された? メールによる新手の攻撃手法とその対策 |
| ◆ | もう仮想化のお試しフェイズは終わりだ! Hyper-V 2.0が基幹システムも仮想化 |
| ◆ | 美人!? まあまあ? 気になる いやし系!! PV急増で「美人時計」がとった手段とは? |

| ◆ | クライアント企業から求められる人材 ⇒IT技術と経営戦略を併せ持つ「戦略家」 |
| ◆ | .NET編集長が実践する「技術情報検索術」 サンプル・コードを簡単に探す“技”は? |
| ◆ | 業務効率と情報セキュリティ対策を両立! 手間なく確実に機密情報を守る方法とは? |

| ◆ | 進化を続ける富士通ストレージETERNUS DX 製品開発者の自信を裏付けるものとは何か |
| ◆ | 運用管理の課題を“2つの観点”から分析 ユーザー満足度の高い「仮想環境」とは? |

| ◆ | 【CTC事例】約30の基幹システムを統合! 膨大なバッジジョブを制御した方法は? |
| ◆ | 仮想化すればコストは削減できるか? 仮想化に必要な「3つの視点」を解説する |
| ◆ | その数、なんと400台以上! グループ内 サーバの「統合管理」によるメリットは? |







