TIL 57 day第6章プロトタイプ

5463 ワード

プロトタイプ

  • JavaScriptはプロトタイプベースの言語です
    :オブジェクトをプロトタイプ(prototype)としてコピー(参照)し、継承と同様の効果
  • を生成します.

    コンセプト(コンストラクション関数、プロトタイプ、インスタンス)

    var instance = new Constructor();
  • Prototypeオブジェクト:Prototypeオブジェクトの内部にインスタンスを格納する方法
    =>インスタンスは、非表示のProperty __proto__を介してこれらのメソッドにアクセスすることもできます.
    instance.__proto__方式では直接アクセスできません=>ブラウザの互換性をサポートしていますが、推奨されていませんObject.getPrototypeOf(instance)/24579142で
  • にアクセス
    var Person = function(name){
      this.name = name;
    }
    Person.prototype.getName = function() {
      return this._name;
    }
    
    var suzi = new Person('suzi');
    suzi.__proto__.getName(); // undefined (error 나지 않음)
    Person.prototype === suzi.__proto__ // true
  • ではありません.=>getNameを実行しました.getNameは関数です!
    =>
  • は、このオブジェクトにバインドされたエラーのために予想値がエクスポートされませんでした.
  • getName関数では、Refelect.getPrototypeOf(instance)ではなく、suziという名前のオブジェクトです.
    =>suzi.__proto__は省略可能なpropertyである.
  • suzi.__proto__.getName
    => suzi(.__proto__).getName
    => suzi.getName
    コンストラクション関数のprototypeに何らかのメソッドまたはpropertyがある場合、インスタンスは独自のようにメソッドまたはpropertyにアクセスすることもできます.
    var Constructor = function (name) {
      this.name = name;
    }
    Constructor.prototype.method1 = function(){};
    Constructor.prototype.property1 = 'Constructor Prototype Property';
    
    var instance = new Constructor('Instance');
    console.dir(Constructor); // 1번
    console.dir(instance); // 2번

    2番が__proto__と出力されたのは、インスタンスがそのコンストラクション関数の名前をその関数のインスタンスとしてマークしているからです.
    var arr = [1, 2];
    console.dir(arr);
    console.dir(Array);
  • 例のContructorはArrayである.リファレンスプロトタイプ
    =>__proto__省略可能
    =>インスタンスは、push、pop、forEachなどのメソッドを呼び出すように
  • を呼び出すことができる.
    インスタンスはfrom、isArrayなどのメソッドを直接呼び出すことはできません(
  • Arrayのプロトタイプ構成ではありません)
    =>Arrayジェネレータ関数から
  • に直接アクセスする必要があります.

    コンストラクタ

  • コンストラクタのpropertyとして、プロトタイプオブジェクトの内部にconstructorというpropertyが存在する.
    =>オリジナルコンストラクション関数(自己)を参照
    =>これはインスタンスからそのプロトタイプが何であるかを知る手段である.
  • var arr = [1,2];
    Array.prototype.constructor === Array // true
    arr.__proto__.constructor === Array // true
    arr.constructor === Array //true
    
    var arr2 = new arr.constructor(3, 4);
    console.log(arr2); // [3, 4]
  • コンストラクタを変更しても、参照オブジェクトのみが変更されます.
    =>コンストラクション関数propertyに依存してインスタンスのコンストラクション関数情報を取得することは、必ずしも安全ではありません.
  • 以下は同じオブジェクトです.
  • [Constructor]
    [instance].__proto__.constructor
    [instance].constructor
    Object.getPrototypeOf([instance]).constructor
    [Constructor].prototype.constructor
  • 以下では、同じオブジェクト(プロトタイプ)にアクセスできます.
  • [Constructor].prototype
    [instance].__proto__
    [instance]
    Object.getPrototypeOf([instance])

    プロトタイプチェーン


    1)メソッドオーバーフロー

    var Person = function(name) {
      this.name = name;
    };
    Person.prototype.getName = function() {
      return this.name;
    };
    var iu = new Person('지금');
    iu.getName = function() {
      return '바로 ' + this.name;
    }
    console.log(iu.getName()); // 바로 지금
    呼び出されたのはiuオブジェクト上のgetNameメソッドで、
  • __proto__ではありません.
    =>メソッドオーバーライド
  • メソッド上書きでプロトタイプにアクセスした場合
    : iu.__proto__.getName=>thisはprototypeオブジェクト(console.log(iu.__proto__.getName()); // undefined)を指します.prototypeにname propertyがないため、prototypeにname propertyがある場合、この値が出力されます.
    一般的に、メソッドオーバーライドであれば、自分に最も近いメソッドにしかアクセスできませんが、自分に最も近いiu.__prototypeにもアクセスできます.
  • 2)プロトタイプチェーン

  • すべてのオブジェクトの__proto__は、オブジェクトを含む.プロトタイプ接続
  • var arr = [1, 2];
    arr(.__proto__).push(3);
    arr(.__proto__)(.__proto__).hasOwnProperty(2); //true
  • プロトコルタイプチェーン(プロトタイプチェーン):あるデータの__proto__プロトコルにおいて、__proto__プロトコルはまた
  • にリンクされる.
  • プロトタイプチェーン:チェーンに沿って
  • を検索
    var arr = [1, 2];
    Array.prototype.toString.call(arr); // 1, 2
    Object.prototype.toString.call(arr); // [object Array]
    arr.toString(); // 1, 2
    
    arr.toString = function() {
      return this.join('_');
    };
    arr.toString(); //1_2

    3)対象メソッドのみの例外

  • の任意のジェネレータ関数のプロトタイプはオブジェクトである必要があります.したがって、__proto__は常にプロトタイプチェーンの最上位に存在します.参照型データだけでなく、基本型データもObject.prototypeに繰り返しアクセスでき、最終的に対象となる.原型に近づくことができるからです.
    =>オブジェクトにのみ機能する専用メソッドはObjectです.スタティックメソッド(static method)で原型ではないオブジェクトを付与するしかありません!
  • 4)マルチプロトコルチェーン

    var Grade = function() {
      var args = Array.prototype.slice.call(arguments);
      for (var i = 0; i <args.length; i++) {
        this[i] = args[i]
      }
      this.length = args.length;
    };
    var g = new Grade(100, 80);
    
    Grade.prototype = [];
    
    console.log(g);
    g.pop();
    console.log(g);
    g.push(90);
    console.log(g);
    アレイのようなオブジェクト
  • は、アレイの形態を有するが、アレイの方法は使用できない.
  • のインスタンスで配列方法を直接使用してもらいたいです!
    =>__proto__、すなわちGrade.Prototypeに配列のインスタンスを表示させるとよい.