web newbie このページをアンテナに追加 RSSフィード

2007-04-19 続・Javascript初心者によりprototype

[]prototype図示とnewの挙動

多くの方に読んでもらえたのが何より嬉しい。

ブログ、書いて良かった、純粋に。ありがとうございます。


でも、はてぶページとか社内とかで、

「でも...もう一歩しっくりこない」という声もあって。。


話をしてて、以下の2つが理解できると、

Javascriptprototype指向がしっくりくる(かもしれない)ことがわかった。

で、僕なりにそれをまとめてみようと思った。(くどくない程度に^^;)


それは次の(1)と(2)の理解である。

(1)prototypeオブジェクトの関連を図でイメージする。

(2)newの挙動を把握する。


この2つをきっちり理解すれば、

少なくとももう少しprototype指向がしっくりくると思う。


だから、前の記事でよく分からなかった人は、読んでいただければと思う。

題材は前回の記事と同じく、赤い箱と青い箱を取り上げる。

var Box = function(size){
    this.size = size;
}
Box.prototype = { color: "red" };
var redBox1 = new Box(10);
var redBox2 = new Box(11);
Box.prototype = { color: "blue"};
var blueBox = new Box(12);

(1)prototypeオブジェクトの関連

まずは、(1)prototypeオブジェクト{}の関連を図でイメージする。

f:id:yupug:20070420022943p:image

オブジェクトprototypeの関係が直観的に理解できるかもしれない。


ポイントは、

redBox1, blueBoxは、BoxやBox.prototypeを見ているのではなく、
{ color: ** }のオブジェクトを指している(参照をもっている)

ということだ。

クラス指向の考えを引きずると、redBox1, blueBoxは、

BoxとかBox.prototypeを指しているように誤解しやすい。


Box.prototypeは実行時に決まるオブジェクトを指している。

(ややくどいけど)だから、上のコードの後に以下のようにすると...

Box.prototype = redBox1.prototype;
Box.prototype.color = "yellow";
alert(redBox1.color); //yellow
alert(redBox2.color); //yellow
alert(blueBox.color); //blue

(Box.prototypeが指すオブジェクトを青い箱から赤い箱に変えた。)

これらの結果が前より納得いくものとなっていたら幸いである。


(2)newの挙動

(1)のprototypeが理解できたら、あとはnewが理解できれば、

javascriptprototypeに大してビビることはなくなると思う。


newに関しては、僕はこの記事がすごく分かり易かった

JavaScript の new 演算子の意味

だから、nanto_viさんの文言をお借りし、書いてみる。


例えば、この新しい青い箱を作るという処理を思い浮べて、読んでもらえればとおもう。

var blueBox = new Box(12);

"new" の挙動

  1.  新しいオブジェクト{}を作成する
  2.  1で作成したオブジェクトprototypeに、Box(関数オブジェクト)のprototypeが格納している参照を格納する。(上の例では、{color: "blue"}オブジェクトへの参照)
  3.  1で作成したオブジェクトへの参照を、関数Box内のthisにセットし、関数Boxを呼び出す。引数が記述されていれば(例では12), それを関数Box実行の引数とする。
  4.  1で作成したオブジェクトへの参照を返す。

正確な定義はひとまず置いておいて、これがnewの挙動である。

新しく作るオブジェクト初期化を行いたい場合ば、

Boxの処理の中に this を記述すれば、初期化処理を行うことができる。

var Box = function(size) {
  this.size = size;
};

Box.prototypeが指すオブジェクトに影響を与えず、

新たに作成したオブジェクトにだけ処理[ex.プロパティを追加]をしている。

こうした関数オブジェクトBoxはコンストラクタと呼ばれるが、

new との協業によって新たなオブジェクトを作成していることからも、まさしくコンストラクタである。

一方、クラスというものは存在しない。

実際Ecmascript仕様書にも、

コンストラクタは明記されているが、クラスという言葉は出てこない。

(全部隅から隅まで見たわけではありません、、、^^;)


一般に言うクラスの役割をするのは、

まさにBox.prototypeが指しているオブジェクトであり、

これがprototype指向の核なのかな、と思った。


以上、分かっている人には当たり前の、つまらない説明かもしれないが、

少しでも納得した人がいてくれたら、幸せだなぁと思います。

prototypeを把握した上で、

prototype.jsを読んでみるのも面白いと思います。(extendとか)

mal_bluemal_blue 2007/04/21 12:03 わざとかもしれないけど、重箱の隅。
prototype と __proto__ を書き分けた方がいいかも。コンストラクタ関数が雛型として持つのが prototype 、オブジェクトが実行時に参照するのは __proto__ のチェーン。
・図の中の redbox1,redbox2,bluebox 内にある prototype は __proto__
・nanto_vi さんからの引用で 2. の「1で作成したオブジェクトのprototypeに」の prototype も __proto__

ぎょはぁ!!!!!ぎょはぁ!!!!! 2009/08/16 22:04
ヘイヘイ!!あひひひほはぁwwwwwww ちょwwいきなりごめwwwwww
寝てるだけで5 万もらっちゃって真面目な自分がヴァカらしくなってさwwwww
はぁーいま女シャワー浴びてんだけど、もう1ラウンドでまた5 万くれるってYO!wwwwww
またマグロでさっさと中 出 しするわwwwwwwwww

http://kachi.strowcrue.net/aWTHOZ6/

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yupug/20070419/1177005839