BLOG

プロトタイプ、クラス継承、superのメモ

プロトタイプ継承

別のコンストラクター関数のプロトタイプを受け継いで、機能を流用できるようにすること。

別のコンストラクター関数を受け継ぐこと→継承

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.hello = function() {
  console.log('hello ' + this.name);
}

↑を↓こうする

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.hello = function() {
  console.log('hello ' + this.name);
}

function Japanese(name, age){
    Person.call(this, name, age);
//Person.callで呼び出し、ここの関数コンテキストのthisがPersonに渡り、this.name,this.ageが設定される
}
Japanese.prototype = Object.create(Person.prototype)

const taro = new Japanese('Taro', 23);

console.log(taro);
taro.hello();

console

Japanese {name: "Taro", age: 23}age: 23name: "Taro"__proto__: Person__proto__: hello: ƒ ()constructor: ƒ Person(name, age)__proto__: Objectconstructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable: ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()get __proto__: ƒ __proto__()set __proto__: ƒ __proto__()

hello Taro

ある関数のプロトタイプを別の関数のプロトタイプチェーンに追加することをプロトタイプ継承と表現する。

このようにちょっとした機能の追加もできる。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.hello = function() {
  console.log('hello ' + this.name);
}

function Japanese(name, age, gender){
    Person.call(this,name,age)
    this.gender = gender;
}

Japanese.prototype = Object.create(Person.prototype);

Japanese.prototype.bro = function(){
  console.log('bro'+' your age is ' + this.age);
  console.log('yo ' + 'are you ' + this.gender + ' ?');
}

const hayato = new Japanese('Hayato',27, 'male');


hayato.bro();

console

bro your age is 27
yo are you male ?

クラス

javascriptではオブジェクトを効率よく作成する為の方法として、はじめに「設計図」を用意する必要がある。

その設計図がクラスである。

このコンストラクタをクラスに書き換える


function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.hello = function() {
  console.log('hello ' + this.name);
}

class Person{
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
  hello(){
    console.log('hello' + this.name);
  }
}

これでクラスが完成したこととなる。

上のコンストラクタ関数、プロトタイプを定義するのと、下のクラスで定義するのは実質同じ意味になる。

このクラスはコンストラクタ関数のシンタックスシュガーということになる。

※シンタックスシュガーとはsyntax(構文、書き方ルール的な)を簡単にしたもの

このPersonクラスをインスタンス化してオブジェクトを生成する。

オブジェクトを生成するには「newクラス名()」と書く。

クラスから生成したオブジェクトはインスタンスと呼ぶ。

class Person{
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
  hello(){
    console.log('hello' + this.name);
  }
}

const hayato = new Person('hayato', 27);
console.log(hayato);

console

Person {name: “hayato”, age: 27}

基本的にES6からはこのクラス表記で書く。

とはいえ、コンストラクタ関数、プロトタイプの仕組みの理解もjavascriptの裏側を理解する上で必要である。

クラス継承

クラス継承とは、他のクラスのプロパティとメソッドを継承すること。

プロトタイプ継承のクラス版。

もとはこう

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.hello = function() {
  console.log('hello ' + this.name);
}

function Japanese(name, age, gender) {
  Person.call(this, name, age);
  this.gender = gender;
}

Japanese.prototype = Object.create(Person.prototype);

Japanese.prototype.hello = function() {
  console.log('Konnichiwa ' + this.name);
}

Japanese.prototype.bye = function() {
  console.log('Sayonara ' + this.name);
}

const hayato = new Japanese('hayato', 27, 'Male');

↑が↓こう

class Person {
  constructor(name, age){
    this.name = name;
    this.age = age;
  }
  hello(){
    console.log('yoo ' + this.name);
  }
}


//クラスの継承にはextends
class Japanese extends Person{
  constructor(name, age, gender){
    super(name, age);
    this.gender = gender;
  }
  hello() {
    console.log('Konnichiwa ' + this.name);
  }
  bye() {
    console.log('Sayonara ' + this.name);
  }
}


const hayato = new Japanese('hayato', 27, 'Male');

hayato.hello();
hayato.bye();

console

Konnichiwa hayato
Sayonara hayato

となる。

super

継承元の関数を呼び出すためのキーワード。

下記のように親のメソッドを呼び出せる

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    hello() {
        console.log('hello ' + this.name);
    }
}

class Japanese extends Person {
    constructor(name, age, gender) {
        super(name, age);
        this.gender = gender;
    }

    hello() {
        super.hello();//Personのhelloメソッドを呼ぶ
        console.log('Konnichiwa ' + this.name);
    }

    bye() {
        console.log('Sayonara ' + this.name);
    }
}

const hayato = new Japanese('hayato', 27, 'Male');

hayato.hello();

console

hello hayato
Konnichiwa hayato

注意点

superキーワードの前にJapaneseのthisを使ったプロパティを宣言すると、(this.gender = genderがsuperの上に来るなど)エラーになる。

メソッドのときは順番は関係ない。

superはクラスの中で使用されるもの。