以上、最終回の今回はJavaScriptによるオブジェクト指向について解説した。JavaScriptのオブジェクト指向は「プロトタイプ・ ベースのオブジェクト指向」と呼ばれ、従来の「クラス・ベースのオブジェクト指向」に精通した開発者であればあるほど、なじみにくく感じる概念かもしれな い。しかし、あまり難しく考える必要はない。
繰り返しではあるが、JavaScriptではクラスという抽象的な概念の代わりに、すべての概念が実体を持ったオブジェクト(インスタンス)で 表されるというだけだ。クラス・ベースのオブジェクト指向言語では、クラスを基にオブジェクトを作成していたところが、JavaScriptではオブジェ クトを基に異なるオブジェクトを作成することになっただけなのだ。この1点さえ分かってしまえば、実は、プロトタイプ・ベースのオブジェクト指向も恐れる に足らない。
本稿が、JavaScriptに対して苦手意識を持つ開発者諸氏にとって、これを克服するきっかけとなれば幸いである。
[コラム]オブジェクトと連想配列 本文で、オブジェクト・リテラルの「{名前 : 値, ……}」という表記は、JavaScriptにおける連想配列(ハッシュ)の記法でもあると述べた。これを聞いて、それではオブジェクトはそもそも連想配列なのではないかと考えた方はご明察。 そのとおり、JavaScriptではオブジェクトと連想配列との間に厳密な区別はない。便宜上、オブジェクトと連想配列を(キーワードとして) 使い分けることはあるにせよ、オブジェクトと連想配列とは、JavaScriptの世界においては同一の概念なのである。従って、以下の記述も、意味的に 完全に等価である。
また、オブジェクトのメンバにアクセスするにも、ドット演算子を利用するばかりではない――連想配列のブランケット構文を利用してアクセスするこ とが可能である。逆もしかり、連想配列の各キーに対してドット演算子でアクセスすることも可能だ。そう、連想配列はオブジェクトであり、オブジェクトは連 想配列であるのだから*5。従って、以下の2文は、これまた等価の命令である。
もっと行ってみよう。実は、先ほどのリスト9でさりげなくfor…inループでオブジェクト配下のメンバを列挙するコードを表してみたが、オブ ジェクトが連想配列であることを理解してみれば、これまた直感的に理解できる内容であるはずだ。for…inループは、連想配列から順に配下のキーを取り 出しているというわけだ。 もちろん、先ほどのリストでも示したように、取り出したキーによってブランケット構文でアクセスすることで、メンバの内容を取得することもできる。 ただし、for…in命令による列挙は、すべてのメンバが対象となるわけではないので、注意してほしい。
このコードは、Arrayオブジェクトに属するメンバを順に列挙することを目的としたものである(Arrayオブジェクトではconcat、 join、pop、pushなどのメソッドが公開されているはずである)。しかし、結果はというと、「メンバは一切表示されない」。これはどういうことな のだろうか。 実は、これはArrayオブジェクトのprototypeプロパティがDontEnum属性でマーキングされていることから生じる現象である。 DontEnum属性が付与されたメンバは、for…inループによる列挙の対象から外される。そのため、prototypeプロパティ(プロトタイプ・ オブジェクト)で定義されたすべてのメンバはfor…inループでは表示されないというわけだ。この事情は、ほかのオブジェクトのメンバについても同様で ある。 ちなみに、JavaScriptではそのほかにもメンバの特性を決めるための属性として、以下のようなものを用意している。
ただし、これらの属性はあくまでJavaScript内部的なもので、アプリケーション開発者が直接に触れることはできない(例えば、自作オブ ジェクトのメンバに対してDontEnum属性を追加したり、組み込みオブジェクトのメンバからDontDelete属性を外したりということはできな い)。 |
댓글 없음:
댓글 쓰기