引き続き、オブジェクトのお話をまだまだしていくぞ。
まだあんの?
まだまだ。もう腹をくくるんだな
もうわかったよ。やるよ。やればいいんでしょ
今回はオブジェクトの継承についてやっていこう
前回、プロトタイプチェーンという話をした。
・最終的にObjectのprototypeを参照する。
・Objectは全てのオブジェクトの親である
こんな感じだ。
で、チェーンは
1:インスタンス化したメソッド参照
2:インスタンス元のprototype
3:Objectクラスのprototype
の順番だったが、Objectクラスのprototypeを見に行く前にさらに別オブジェクトのprototypeのものを
参照する事ができるのだ。
そうする事を継承と呼ぶ
はっはーん。なるほど、分からん
こいつも実際にやってみたほうが分かりやすいかな。
Object.prototype.myMethod = function(){ alert('あのう。Objectから呼ばれたんですけどぉ'); }
// 使いたいオブジェクト
var myObj = function()
{
this.name;
this.spellCard;
}
// 継承されるオブジェクト
var myObj2 = function()
{
this.saySpellCard = function ()
{
alert(this.name+'「スペルカード! '+this.spellCard+'」');
}
}
// プロトタイプにインスタンス化する事で継承。順番に注意!!
myObj.prototype = new myObj2();
myObj.prototype.sayName = function ()
{
alert(this.name+'のターン');
}
var chiruno = new myObj;
// プロパティの設定
chiruno.name = 'チルノ';
chiruno.spellCard = 'アイシクルフォール!';
// メソッドの実行
chiruno.sayName(); // myObjのprototype
chiruno.saySpellCard(); // myObj2のメソッド(継承したもの)
chiruno.myMethod(); // Object暮らすのprototype
ううむ。なんかごちゃごちゃしてきたね
順番に見ていこう
まず、オブジェクトが2つ作られているのはわかるな。
そだね。そこは大丈夫
次に、使いたいオブジェクトのprototypeに継承されるオブジェクトがまんまインスタンス化されている。
prototypeは順番に参照されるので、ここに新しく入れてやる事で、使用する事ができるってわけだ。
順番に注意!と書いてあるがこれは本当に注意だ。
myObj.prototypeの中をmyObj2のメソッドで上書きしている事になる。
myObj.prototype.sayNameを先に入れておくとこんな事が発生する。
myObj.prototype.sayName = (略) // sayNameメソッドはあるよ
myObj.prototype = new myObj2(); // 全部上書きするね!
myObj.prototype.sayNameは上書きされてなくなる
なので、順番に注意!とはこの事なんだ
後にすれば、後のメソッドを追加するから、myObj2のは大丈夫って事か
でも、myObj2の中にも、sayNameがあったらそれは上書きされるんだよね。
名前が一緒だから実行方法は同じでも
myObj2の処理じゃなくて、追加したやつになるって事だよね
その通り、名前の付け方には注意が必要だ
メソッド実行部分はまぁそのままなので割愛するが
この例の場合の各メソッドが実行されるチェーンについてはこうなっている。
■sayNameメソッド
1:インスタンス化された中身を探す。
↓無かった
2:インスタンス元のprototypeを見てみる
→あった!実行
■saySpellCardメソッド
1:インスタンス化された中身を探す。
↓無かった
2:インスタンス元のprototypeを見てみる
↓無かった
3:継承したmyObj2のprototypeを見てみる
→あった!実行
■myMethodメソッド
1:インスタンス化された中身を探す。
↓無かった
2:インスタンス元のprototypeを見てみる
↓無かった
3:継承したmyObj2のprototypeを見てみる
↓無かった
4:Objectクラスのprototypeを見てみる
→あった!実行
継承しているから探しに行く回数も増えているね
特にObjectクラスに追加したやつは一番大変だな。
って事は、myObj2の中でもmyObj3みたいなのを作って継承させてたら
myObjの中でもmyObj3のが使えたりしてーみたいな。まさかね
使えるんだな。これが
使えんのかよ
Object.prototype.myMethod = function(){ alert('あのう。Objectから呼ばれたんですけどぉ'); }
// 使いたいオブジェクト
var myObj = function()
{
this.name;
this.spellCard;
}
// 継承されるオブジェクト
var myObj2 = function()
{
this.saySpellCard = function ()
{
alert(this.name+'「スペルカード! '+this.spellCard+'」');
}
}
// myObj2内で継承されるオブジェクト
var myObj3 = function()
{
this.winWord;
this.sayWinWord = function ()
{
alert(this.winWord);
}
}
// myObj2に継承
myObj2.prototype = new myObj3();
// プロトタイプにインスタンス化する事で継承。順番に注意!!
myObj.prototype = new myObj2();
myObj.prototype.sayName = function ()
{
alert(this.name+'のターン');
}
var chiruno = new myObj;
// プロパティの設定
chiruno.name = 'チルノ';
chiruno.spellCard = 'アイシクルフォール!';
chiruno.winWord = 'あたいったら最強ね!';
// メソッドの実行
chiruno.sayName(); // myObjのprototype
chiruno.saySpellCard(); // myObj2のメソッド(継承したもの)
chiruno.sayWinWord(); // myObj2のメソッド(継承したもの)
chiruno.myMethod(); // Object暮らすのprototype
うお…まじだ…
きちんとmyObj3のプロパティにもアクセスできているね
親の親だから、じいちゃんばぁちゃんオブジェクトだね。
そう、こんな風にどんどん継承していくことができるのだ。
でもこれ、ちゃんと考えて作らないと大変な事になる気がするんだけど
例えば?
こうなった場合さ、さっきけーねがチェーンの順番を解説してくれたじゃん
そこに一つ追加されて、最後のObjectクラスのprototypeに辿り着くまで、長くなっちゃうよねと思って
だから、むやみに継承しまくってたら、JSの中の人探すのめっちゃ大変じゃん
その通りだ!!!後はやたらコードがごちゃごちゃして分からんって事もありうる
この辺は設計時にきちんと決めるべきところだな
今日は冴えてるじゃないか
アタイですから
まったく。まぁいい
さぁ、ここまでくれば分かるだろう。
良く書かれている言葉
【javascriptはプロトタイプベースのオブジェクト指向言語である!】
だ。
そだね!
あんだけ共通化だなんだやったし、継承もプロトタイプにブチ込んでるし
今なら、その言葉聞いても
「まさにその通り!!!」って自信持って言えるよ
まぁ、まだ細々した所は続いていくと思うが、一つの大きな壁を超えられたようだ。
今回はここまでにしよう
けーねありがとう!