こんにちはタクゾウです。
今回は、JavaSctiptでクラスを使うためのプロトタイプについて復習したいと思います。
プロトタイプとは
JavaScriptにはクラスという概念がないですが、このクラスの代わりになるのがプロトタイプです。
※ES6(ECMAScript2015)ではあるけど、対応ブラウザがまだまだ少ない。
プロトタイプとは、prototyopeプロパティのこと
prototypeに何かを入れておけば、インスタンス化した時に引き継ぐことができます。(オブジェクト指向でいう、staticプロパティやstaticメソッドが作れる。)
コンストラクタだと不便な場合がある!
コンストラクタの書き方では、処理を後から変更したい場合に不便な時があります。
モンスターのコンストラクタからインスタンスを作成するコードを例に説明していきます。
var Monster = function(name, hp, attack){
this.name = name;
this.hp = hp;
this.attack = attack;
this.doAttack = function(){
console.log(this.name + 'は' + this.attack + 'のダメージを与えた');
}
}
var dragon = new Monster('ドラゴン', 9999, 8000);//dragonのインスタンスを作成
var slime = new Monster('スライム', 100, 1);//slimeのインスタンスを作成
console.log(dragon.doAttack());//ドラゴンは8000のダメージを与えた
console.log(slime.doAttack());//スライムは1のダメージを与えた
doAttackメソッドの中の処理を変更したい場合を考えると、
インスタンスにメソッドがコピーされて別々になっているので、それぞれのインスタンスを変更させる必要がる。
dragon.doAttack = function(){
console.log(this.name + 'は動けなかった');
}
slime.doAttack = function(){
console.log(this.name + 'は動けなかった');
}
これでは数が多い場合に修正が大変になります、、
これを解決できるのがprototypeです。
prototypeを使った場合
prototypeでメソッド変更に対応できるように記述した例がこちらです。
var Monster = function(name, hp, attack){
this.name = name;
this.hp = hp;
this.attack = attack;
}
Monster.prototype.doAttack = function(){
console.log(this.name + 'は' + this.attack + 'のダメージを与えた');
}
var dragon = new Monster('ドラゴン', 9999, 8000);
var slime = new Monster('スライム', 100, 1);
console.log(dragon.doAttack());
console.log(slime.doAttack());
コンストラクタとの違いは、コンストラクタを作った後に関数部分は、
prototypeを指定して作成しています。
この記述で先ほど同様にメソッドを変更したい場合は、プロトタイプの記述を変更するだけで
全てのインスタンスのメソッドを変更することができます。
Monster.prototype.doAttack = function(){
console.log(this.name + 'は動けなかった。');
}
・インスタンスごとにメソッドを増やさないので、メモリの節約になる!!
・インスタンスした後にprototypeを追加してもインスタンスで使用することができる!!
プロトタイプチェーン
プロトタイプチェーンについても簡単に説明します。
prototypeを使ってオブジェクト指向でいう「継承」ができる仕組みのこと
prototypeの中に別のインスタンスをいれておけば、そのインスタンスのプロパティやメソッドが利用できる。
継承元のインスタンスがかわれば、継承先にも反映される。
var Creature = function(){};
Creature.prototype = {
doAttack : function(){
console.log(this.name + 'は' + this.attack + 'のダメージを与えた');
}
};
var StrongCharacter = function(name, hp, attack, cry){
this.name = name;
this.hp = hp;
this.attack = attack;
this.doCry = function(){
console.log(cry);
}
};
var WeakCharacter = function(name, hp, attack){
this.name = name;
this.hp = hp;
this.attack = attack;
this.doRun = function(){
console.log(this.name + 'は全速力で逃げた');
}
};
StrongCharacter.prototype = new Creature();
WeakCharacter.prototype = new Creature();
var dragon = new StrongCharacter('ドラゴン', 9999, 8000, 'ギャフーン');
var slime = new WeakCharacter('スライム', 100, 1);
dragon.doCry();//ギャフーン
dragon.doAttack();//ドラゴンは8000のダメージを与えた
slime.doAttack();//スライムは1のダメージを与えた
slime.doRun();//スライムは全速力で逃げた
この書き方により、継承元である「Creature」のdoAttack()メソッドが継承先のインスタンスでも使用できるようになります。
もちろん、Creatureの内容を変更すると継承先のインスタンスも変更されます。
まとめ
規模が大きいシステムでは、プロトタイプを使うと便利なので、使えるようにしましょう。
コメントを残す