プログラマのkinuです。普段よく使いますがあまり理解せずに使ってたjavascriptのオブジェクトについて調べました。 javascript はオブジェクト指向プログラムをサポートした言語です。 PHPなどのクラスを実装し、オブジェクトを生成して動作させるクラスベースのオブジェクト指向ではなく、プロトタイプベースのオブジェクト指向です。プロトタイプというのがどういうものを指してるのかまだ理解できてないですが、とりあえずオブジェクトからオブジェクトを生成して動作させるということはなんとなくわかりました。
生成のしくみ
javascript のオブジェクト生成の単純な例です。
[code] var A = function (x) { this.x = x; }; A.prototype.x = 0; var a = new A(1); [/code]
http://d.hatena.ne.jp/maeharin/20130215/javascript_prototype_chain の記事を参考にインスペクタでのぞきながら自分なりに図にまとめました。
四角はオブジェクト、矢印はプロパティです。点線の矢印は構造と直接関係ない補助的なものです。 この図から実際使うオブジェクトのほかにオブジェクトを生成するオブジェクト(コンストラクタ)とベースになるオブジェクト(プロトタイプ)があることがなんとなくわかります。 このままだとわかりづらいので図にまとめると、
つまり、コンストラクタをnewするとprototypeプロパティにもったオブジェクトをもとにオブジェクトを生成してくれるということです。あとついでにコンストラクタの処理を生成したオブジェクトで実行してくれます。
__proto__ってなに?
プロパティproto
は内部プロパティprototypeの値でプロトタイプをもってます。
[図1]でいうと、a
はA.prototype
を、A.prototype
はObject.prototype
をもっています。
プロパティ(またはメソッド)を使うときにこのprototypeをたどって探索します。これをプロトタイプチェーンといいます。
オブジェクトがオブジェクトを生成する
あらためて[図1]をみると[図2]の形がけっこうみつけられます。
a
をみてみるとA
でA.prototype
をもとにつくられています。A
もFunction
でFunction.prototype
をもとにつくられ、A.prototype
もObject
でObject.prototype
をもとにつくられてます。
この仕組みでオブジェクトが生成されていることがわかりますね。
Object.create()
コンストラクタをnewしてオブジェクトを生成する方法のほかにもオブジェクトを生成する方法もあります。それはObject.create()
です。
以下のようにして使います。
[code] var a = Object.create(Object.prototype); a.x = 1; [/code]
これで[コード1]とほぼ同じオブジェクトが生成されます。
「ほぼ」といっているのはコンストラクタから生成したときに自動に設定されるプロパティconstructor
がこれでは設定されません。これはinstanceof
で使われているプロパティなので使い方によっては注意が必要です。
実は[コード2]はObject.create()
がなくても
[code]
var a = {};
a.x = 1;
[/code]
と書いても同じことができます。あれ、Object.create()
いらないんじゃ…と思っちゃいそうですが、既存のオブジェクトからオブジェクトをつくるときに役立ちます。
例えば,
[code] var a = {}; a.x = 1; var b = Object.create(a); b.y = 1; [/code]
のようにすると既存のオブジェクトを簡単に拡張できます。
まとめ
今回はjavascriptのオブジェクトの生成について調べました。 クラスを作らなくてもオブジェクトが作れるのはプロトタイプベースの利点なのかなあなんてふんわり理解できたような気がします。このあたりは実際使うとときがきて実感するんじゃなかろうか。 またクラスベースっぽいふるまいもできるのでそれぞれの特性を生かして使いわけて実装できるという点はすごくいいなと思いました。その分いろいろと知っておく必要はありますが。 あと、今回プロトタイプチェーンという概念がでてきましたがスコープチェーンというのもあるらしいです。まだまだ知らないことも多いですがこれからも暇をみつけて勉強していきたいです。
参考にしたWebページ
- http://d.hatena.ne.jp/maeharin/20130215/javascript_prototype_chain
- http://nanto.asablo.jp/blog/2005/10/24/118564
- http://www.slideshare.net/yuka2py/javascript-23768378
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create
- http://compute-taso.blogspot.jp/2013/04/objectcreate.html