JavaScriptのプロトタイプとプロトタイプチェーンを深く理解する(経典の継承方法を付帯する)

17677 ワード

まず、JavaScriptの変数の種類を復習します.
  • 値タイプ(基本タイプ):String、Number、Boolean、Unidefined、Null、Symbol
  • 引用タイプ:Object、Aray、Funct
  • 値の種類:スタックに保存されます.保存とコピーは値そのものです.方法の終了に伴って自分で廃棄します.引用の種類:ヒープに保存されます.保存とコピーは対象を指す一つの指針です.方法の終了によって破壊されることはなく、何の変数も引用されていない場合、ゴミ回収メカニズムによって処理されます.
    JavaScriptでは、オブジェクトは通常のオブジェクトと関数のオブジェクトに分けられます.new Functionによって作成されたオブジェクトはすべて関数オブジェクトで、その他はすべて普通のオブジェクトです.Object、FunctionはJavaScriptが持つ関数の対象です.ここでは証明しません.関数オブジェクトにはプロトタイプの属性があります.この属性は関数のプロトタイプオブジェクトで、プロトタイプオブジェクトは関数を定義するときに作成されます.
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayName=function(){
            console.log(this.name,this.age);}
    }
    Person.prototype.eat=function () {
        console.log(" ");
    }
    var p1=new Person('a',1);
    var p2=new Person('b',2);
    p1.sayName();// a 1
    p2.sayName();// b 2
    console.log(p1.constructor == Person);//true
    console.log(p2.constructor == Person);//true
    console.log(Person.prototype);//{constructor: ƒ}
    console.log(Person.prototype.constructor==Person);//true
    console.log(p1.__proto__);//{constructor: ƒ}
    console.log(p1.__proto__ === p1.constructor.prototype);//true
    console.log(p1.__proto__ === Person.prototype);//true
    
    prototypeはデフォルトのconstructor属性を持っています.この属性はprototypeがある関数、すなわちPerson.prototype.com nstructor==Personを指します.例p 1とp 2のコンストラクションとPerson.prototypeのコンストラクタはいずれもPersonであることが分かりました.だからPerson.prototypeもPersonの例です.つまり前述のPersonは作成時にインスタンスオブジェクトを作成し、そのプロトタイプに値を付けました.
    原型を言いましたが、その原型チェーンは何ですか?普通のオブジェクトにはプロトタイプの属性はありませんが、プロト.を選択します言い換えれば、どの対象にも__uがあるということです.プロト.属性は、関数オブジェクトのみプロトタイプの属性があります.全ての対象の_uプロト.全部そのコンストラクションのprototypeを指しています.実例p 1の_uプロト.その構造関数を作成するプロトタイプのオブジェクトを指します.p 1._uproto_==p 1.com nstructor.prototype.じゃ、問題が来ました.proto_==Person.prototype、Person.prototypeという対象もあります.プロト.属性は誰を指しますか?その構造関数は誰ですか?
     console.log(typeof Person.prototype) //Object
    
    答えはPerson.prototypeです.proto_==Object.prototype,継続しやすい,Object.prototype.u.プロト.誰を指しますかそれはnullです.プロトタイプチェーンはプロトタイプのオブジェクトから構成されていますが、JavaScriptにはすべてのオブジェクトがあります.プロト.属性は、そのコンストラクタのプロトタイプを指します.プロト.オブジェクトを連結してプロトタイプチェーンを作りました.プロトタイプチェーンは属性検索機構を持っています.対象の属性を検索する場合、インスタンス自体がその属性が存在しない場合、プロトタイプチェーンに沿って1つ上のレベルに検索し、該当する内容を出力します.最上階のObject.prototypeが見つかったら、undefinedを出力します.定番の栗を取り出す
    var animal = function(){};
    var dog = function(){};
    
    animal.price = 2000;
    dog.prototype = animal;
    var tidy = new dog();
    console.log(dog.price) //undefined
    console.log(tidy.price) // 2000
    
    dogのprice属性にアクセスすると、見つけられませんでした.dogという関数のプロト.誰ですか?関数の対象は全部プロト.すべてFuntion.prototypeを指しています.空の関数ですから、後のチェーンにprice属性がありません.tidyのprice属性を訪問した時も見つけられませんでした.プロト.そのコンストラクタのプロトタイプ、つまりdog.prototypeを指します.プロトタイプチェーンのリンクはインスタンスと構造関数のプロトタイプの間に存在していると結論した.
    半日のプロトタイプとプロトタイプのチェーンは一体何に使いますか?プロトタイプによって対象の属性継承が可能です.以下に4つの経典継承方法を紹介します.
  • プロトタイプチェーンは、コア思想を継承する:親の例をサブクラスのプロトタイプとする.利点:操作が簡単で、父の新しいプロトタイプの方法と属性は、サブクラスにアクセスできます.短所:相続が実現できず、親に渡参できない.
  • function child() {}
    child.prototype=new Person("l",24);
    var c = new child();
    c.sayName(); // l 24
    
  • は、親クラスにおいて、thisによって指定された属性および方法を、カルルまたはappyを用いて、サブクラス作成の例にコピーするコア思想を構成する.利点:複数の父親のクラスをcallすることができますが、複数の相続を達成するために、親のクラスに参加することができます.短所:親の例の属性と方法だけを引き継ぎます.原型の属性と方法は継承できません.
  • function child() {
        Person.call(this,"j","25");
    }
    var c = new child();
    c.sayName(); //j 25
    c.eat(); // c.eat is not a function
    
  • グループは、コア思想を継承する:親の構造を呼び出し、親の例をサブクラスの原型とする.利点:父に伝わることができ、原型の属性と方法を継承することができます.短所:父の構造関数を二回呼び出しました.
  • function child() {
        Person.call(this,"k","26");
    }
    child.prototype=new Person();
    var c = new child();
    c.sayName(); // k 26
    c.eat(); //  
    
  • 寄生グループは、寄生方式により、親の実例となる属性を切り落としたという核心思想を継承する.長所:完璧です.短所:やや複雑です.
  • function child() {
        Person.call(this,"h","27");
    }
    (function () {
        var Super = function () {};
        Super.prototype = Person.prototype;
        child.prototype = new Super();
    })();
    var c = new child();
    c.sayName(); //h 27
    c.eat(); //