お寿司か焼き肉食べたい

まじめな事からしょーもない事まで
めにゅーを開く(投げやり)

継承したりとか色々なんやかんやできるんだって

少しつっこんだ内容のオブジェクト。
理解を深めるのは非常に大事です。

プロトタイプって何。

JSは【プロトタイプベースのオブジェクト指向言語】と呼ばれています。
プロトタイプとは【親のモノ(メソッド)を子が使えるようにする】って事を実現するために作られた考え方なのデス。

親と子?

親とは生成したObjectそのもの。
子とはそのObjectをインスタンス化したもの、という事になります。

インスタンス化?

インスタンス化とは、親オブジェクトの内容を子が使えるようにする事
例えば、配列を生成する時に、 【var array = new Array();】ってしてましたよね
かいつまんで言うと、【new】←こいつがある事でインスタンス化されるという事なのです。

親のものを子が使えるってだから何?

【var array = new Array();】
上記の例では【Arrayオブジェクト】が親、【array変数】が子になります。 その前に少しだけ、Arrayオブジェクトについて。

Arrayオブジェクト

このオブジェクトですが、既に用意されているオブジェクトの一つです。
この中に、pushメソッドやらが用意されているわけです。
これらは基本的に【インスタンス化】しないと使えないものです。

親・・・子・・・うっ(´;ω;`)

では、インスタンス化に戻ります。

【array】のままでは普通の変数なので、push関数とか知らないわけです。
var array.push('hoge');とかしても、お前何言ってだ?と言われるわけです。

ここで【親オブジェクト】を【遊び方冊子】という言葉に変えてみます。
そして、【使いたいメソッド】を【コマ回し】という言葉に変えてみます。

【子】に対して、【コマ回し】をしてよ。と伝えます
しかし、【子】は【コマ回し】のやり方が分からず困ってしまいます。
そこで、【遊び方冊子】を【子】に貸してあげます。
そこで、再度【子】に【コマ回し】をしてよ。と伝えると
【子】は【遊び方冊子】にのっている【コマ回し】の方法を見て理解できたので
無事に【コマ回し】をする事ができました。

インスタンス化ってのはこんなニュアンスの事なのです。
ちなみに、【遊び方冊子】を【子】に貸してあげます。の所がインスタンス化している部分になります。

プロトタイプに戻る

オブジェクトには、_proto_というメソッドが自動的に生成されます。
この中に入っている内容が、子でも分かるようになっているって事です。
上記でいう、【遊び方冊子】の事ですね。

では実際に作ってみる

var obj = {};

obj.prototype.data = '大和型一番艦、大和。';
obj.prototype.view = function (){ alert(this.data); };

var ins1 = new obj();
ins1.view();

obj.prototype is undefined
叱られました。
オブジェクトだからオブジェクトを生成しましたが、これじゃないんだよなぁという事
今回のように、prototypeを使ってアレコレする場合は、通常のオブジェクトではなく
関数を使います。(これを【関数オブジェクト】と呼ぶらしいです)
新しい単語だしまくりですいません。

function obj(){};

obj.prototype.data = '大和型一番艦、大和。';
obj.prototype.view = function (){ alert(this.data); };

var ins1 = new obj();
ins1.view();

上記コピペしてもらうと動きます。
無事にalertが出ると思います。

少し待っていただこう。

所で、上記ではなくってさ

function obj()
{
  this.data = '大和型一番艦、大和。';
  this.view = function (){ alert(this.data); };
};

var ins1 = new obj();
ins1.view();

としても動きます。
まったく同じ動きします!!!
ただ、それでもprototype型を使用するのかと申しますと
断然早い

なんで早いんや!!!!

では、先ほどの遊び方冊子の例をまた引っ張りだすと、以下の違いがでます。

  1. prototype型のほう
    遊び方冊子を一回渡すだけ、その後はその内容にそって遊ぶ
  2. prototype型じゃないほう
    コマ回しをするたびに、遊び方冊子をもらって確認して遊ぶ

要するに、【毎回メソッドが生成されている】って事です。
余分な動きが入るわけですね。そりゃスピードの違いが出るわけです。

今度は子が複数おる場合

前回の例では、子は1人でした。
複数の時はどうなるのか。

function obj(){};

obj.prototype.data = '大和型一番艦、大和。';
obj.prototype.view = function (){ alert(this.data); };

var ins1 = new obj();
var ins2 = new obj();

ins1.view();
ins2.view();

単純にインスタンス化の回数を増やしました。
同じalertが2回表示されるはずです。

何ができる?

渡された遊び方冊子は子が自由に使えます。
何もしなければ、デフォルトで渡された通りの内容ですが
その子用になっているので、独自で変更したりすることができます。

function obj(){};

obj.prototype.data = '大和型一番艦、大和。';
obj.prototype.view = function (){ alert(this.data); };

var ins1 = new obj();
var ins2 = new obj();

ins2.data = '大和型二番艦、武蔵。';

ins1.view();
ins2.view();

上記を実行すると分かりますが、インスタンスされた後、それらは独立するため
他のものにも影響を与ええずに、カスタマイズすることができます。
ins1君は、そのまま遊んでいますが
ins2君は、遊び方をカスタマイズして遊んでいる
って事になるのです。

オブジェクトの継承

インスタンス化して親のを子にみたいな話もしましたが
違うオブジェクトをインスタンス化することで、いわゆる【継承】ができるようになります。

//使うオブジェクト
function myObj(){};

// 継承されるオブジェクト
function myObj2(){};
myObj2.prototype.saySpellCard = function (name,txt)
{
 alert(name+txt);
}

// プロトタイプにインスタンス化する事で継承。順番に注意!!
myObj.prototype = new myObj2();
myObj.prototype.sayName = function (name)
{
 alert(name);
}

var ins1 = new myObj;

// メソッドの実行
ins1.sayName('いらっしゃいませ。当店は肉まん専門店となっております。'); // myObj2にあるメソッド(継承したもの)
ins1.saySpellCard('ぼく「いえ、いりません」\n','店員「また、お越しください」'); // myObj2にあるメソッド(継承したもの)

まぁ、ここまで複雑な処理を書くのってあましない気がしますが
継承ができるって便利だなぁと思ったりもします。