prototypeとは
語源
製品開発を進めるうえで基本的な設計に問題がないかどうかを製品相当のテスト品を製造し、チェックしますが、プロトタイプとは、このときに製造されたプログラムの試作版のこと by Weblio辞書javaScriptにおける意味
プロトタイプは、JavaScript オブジェクトが互いに機能を継承するメカニズム by MDN書き方
まずはメソッドを持つオブジェクトを作る
let User = function(name, age) {
this.name = name;
this.age = age;
this.sayHi = function() {
return `Hi, I'm ${this.name}`;
};
}
let user = new User('John', 30);
console.log(user);
console.log(user.sayHi());
//コンソール
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
John
次にこれを prototype を用いてつくる
※prototype の書き方は
【 オブジェクト名.prototype.メソッド名= function() { } 】
let User = function(name, age) {
this.name = name;
this.age = age;
}
User.prototype.sayHi = function () {
return this.name
}
let user = new User('John', 30);
console.log(user);
console.log(user.sayHi());
//コンソール
{ name: 'John', age: 30 }
John
prototypeを使うメリット
2つの書き方の結果はほとんど同じである が一か所違うところが//コンソール
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
//コンソール
{ name: 'John', age: 30 }
上の例ではインスタンス化するときにメソッドもコピーするのに対し、
下の例では、コピーされていない
つまり、prototype を使えば無駄なメモリの消費を抑えられる
prototypeはなぜメモリの消費を抑えられるのか
prototype を用いるとインスタンス化の際メソッドは参照して、用いられるからである
例えば、例のコンストラクタをそれぞれ5回ずつインスタンス化した場合
//上の例
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
{ name: 'John', age: 30, sayHi: [Function (anonymous)] }
//下の例
{ name: 'John', age: 30 }
{ name: 'John', age: 30 }
{ name: 'John', age: 30 }
{ name: 'John', age: 30 }
{ name: 'John', age: 30 }
prototype
(sayHiメソッド)
このようなイメージになる
インスタンス化が多いほど protptype を使うメリットが大きくなる
試しに prototype の中を見てみると
let User = function (name, age) {
this.name = name;
this.age = age;
};
User.prototype.sayHi = function () {
return this.name;
};
let user = new User('John', 30);
console.log(User.prototype.sayHi);
console.log(User.prototype.sayHi());
//コンソール
[Function(anonymous)];
undefined;
メソッドである
console.log(User.prototype.sayHi());
が undefined なのはインスタンス化していないので this.name が undefined のためである
「prototype」による継承
プロトタイプチェーン
中身が空のオブジェクトを3っつ用意しますlet soccerPlayer = function () {};
let baseballPlayer = function () {};
let doctor = function () {};
この 3 つのオブジェクトがそれぞれ持っている「プロトタイプ」を連結させるには
各プロトタイプには連結させたいオブジェクトのインスタンスを代入する
つまり
baseballPlayer.prototype = new soccerPlayer();
「baseballPlayer」と「soccerPlayer」のプロトタイプはそれぞれ参照できる状態である
そしてこうすることで
doctor.prototype = new baseballPlayer();
【soccerPlayer】【baseballPlayer】【doctor】
がそれぞれ繋がったわけでである
継承
let soccerPlayer = function () {};
let baseballPlayer = function () {};
soccerPlayer.prototype.kick = function () {
return 'kick';
};
baseballPlayer.prototype = new soccerPlayer();
let human1 = new soccerPlayer();
let human2 = new baseballPlayer();
console.log(human1.kick());
console.log(human2.kick());
//コンソール
kick;
kick;
baseballPlayer の prototype は soccerPlayer の prototype を継承しているので kick メソッドが使えるわけである