[TIL] Prototype Chain


Javascriptはプロトタイプベースの言語と呼ばれています.オブジェクトを最初に作成するときは、プロトタイプオブジェクトを青写真として、メソッドとプロパティを継承します.1つのプロトタイプオブジェクトは、別のプロトタイプオブジェクトを親オブジェクトとして、その親プロトタイプオブジェクトから属性とメソッドを継承できます.このように複数のプロトコルタイプが継承関係に接続される現象をプロトタイプチェーンと呼ぶ.

__proto__ , constructor, prototype


  • __proto__:オブジェクトのこの属性により、既存のオブジェクトを継承するプロトタイプオブジェクトに近づくことができます.プロトタイプオブジェクトを取得するgetter関数と見なすことができる.基本タイプオブジェクトを設定するsetter関数として使用することもできますが、無効な(破棄された)使用は現在推奨されていません.
  • constructor:すべてのプロトタイプオブジェクトが持つ属性は、コンストラクション関数を参照してください.
  • prototype:すべてのコンストラクション関数が持つ属性.プロトタイプオブジェクトを参照.このアトリビュートを使用して、プロトタイプオブジェクトにタグを割り当てることもできます.
  • instantiation:コンストラクション関数を呼び出してオブジェクトの新しいインスタンス(instance)を作成する動作で、各インスタンスはプロトタイプオブジェクトの属性を共有する.
  • pseudosubclassing before ES6

    function Human (name) {
      this.name = name;
    }
    
    Human.prototype.sleep = function () {
      console.log('Zzz');
    }
    
    Human.prototype.breathe = function () {
      console.log('Inhale, exhale, inhale, exhale...');
    }
    function Student (name){
    	Human.call(this, name); // this의 context를 Human 단계까지 올려주는 메소드
    }
    
    Student.prototype = Object.create(Human.prototype);
    Student.prototype.constructor = Student;
    Student.prototype.learn = function () {
        console.log('Coding...');
    }
    Object.create()メソッドを使用して、HumanプロトタイプオブジェクトをコピーするStudioプロトタイプオブジェクトを作成します.

    subclassing in ES6


    ES 6は従来の複雑な構文を補完し,classキーワード,superキーワードを用いてサブカテゴリを簡潔に行うことができる.
    class Human {
      constructor (name) {
        this.name = name;
      }
      
      sleep () {
        console.log('Zzz');
      }
      
      breathe () {
        console.log('Inhale, exhale, inhale, exhale...');
      }
    }
    
    let me = new Human('Ha Young');
    me.sleep(); // 'Zzz'
    me.breathe(); // 'Inhale, exhale, inhale, exhale...'
    functionではなくclassキーワードを使用して新しいオブジェクトクラスを定義します.
    class Student extends Human {
      constructor (name) {
      	super (name)
      }
      
      breathe () {
        console.log('I live and breathe JavaScript');
      }
      
      learn () {
        console.log('Coding...');
      }
    }
    
    let sparklingWater = new Student('Ha Young')
    sparklingWater.sleep(); // 'Zzz'
    sparklingWater.breathe(); // 'I live and breathe JavaScript'
    sparklingWater.learn(); // 'Coding...'
    extendsキーワードは、StudioがHumandを親とするサブクラスであることを示し、スーパーキーワードを使用して親のプロパティを取得します.(親と子が同じパラメータを使用している場合は、スーパー文を省略できます.)親から継承するメソッドは、子クラスで上書きできます.
    Student.prototype.breathe () {
      Human.prototype.breathe.call(this);
      console.log('I live and breathe JavaScript');
    }
    上書きではなく拡張的に基本動作を変更する場合は、callまたはapplyで親クラスのメソッドを呼び出し、コンテンツを追加できます.

    prototype chain in action




    SteveがHumanの新しいインスタンスを作成する場合、Steveの__proto__属性からHumanのプロトタイプオブジェクトにアクセスできます.

    同様にHumanのプロトタイプオブジェクトの__proto__属性からオブジェクトのプロトタイプオブジェクトにアクセスできます.



    meという名前のStudioの新しいインスタンスを作成する場合は、Humanではなく、meの__proto__プロパティからStudioのプロトタイプオブジェクトにアクセスできます.

    meはStudioのインスタンス(StudioはHumanから継承)であり、Humanのインスタンスでもあるが、steveはStudioのインスタンスではなくHumanのインスタンスである.