LoginSignup
0
0

More than 1 year has passed since last update.

【javaScript】prototypeとは?

Last updated at Posted at 2022-04-23

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メソッドが使えるわけである

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0