JavaScriptプロトタイプとプロトタイプチェーンの再理解

11691 ワード

1.はじめに


JS原型と原型チェーンについて私は以前jsを習ったばかりで文章を書いたことがありますが、先日ひっくり返してみました.何の鬼ですか.これは私が書いたのですか.自分でも読めなくなったので、考えを整理し直して、この編を書きました.
プロトタイプとプロトタイプチェーンがjsの難点であることもポイントであり、プロトタイプとプロトタイプチェーンを理解していないという言葉があり、まだ本格的な入門の先端がないとしても.また、プロトタイプとプロトタイプチェーンは面接で欠かせない話題になります.この文章を読んでみると、原型と原型チェーンについて深く理解できると信じています.

2.関数オブジェクト


JSすべてのオブジェクトは、関数オブジェクトと一般オブジェクトに分けられます.new Function()で作成されたオブジェクトはすべて関数オブジェクトです.関数オブジェクトにはprototypeプロパティと__があります.proto__で行ないます.
prototype
JS設計当初は単純継承を実現するためにprototype属性を導入し,プロトタイプオブジェクト(明示プロトタイプ)とも呼ばれる.
//    
function Animal(){};  

console.log(typeof Animal.prototype) //Object  
console.log(typeof Object.prototype) // Object  

本質的にprototypeは一般的なオブジェクトであり、関数オブジェクトのコンストラクション関数によって作成されたインスタンスであることがわかります.Animalが作成されると、自動的にインスタンスが作成され、prototypeに割り当てられます.
しかし、特別な例がある.prototypeはプロトタイプオブジェクトであり,本質は関数オブジェクトである.関数オブジェクトとしてprototypeプロパティはありません.
console.log(typeof Function.prototype) //    Function  
console.log(typeof Function.prototype.prototype) //undefined        prototype  

__proto__ツールバーの
すべてのオブジェクトobj(nullとundefinedを除く)に__があります.proto__プロパティ(暗黙のプロトタイプ),_proto__属性は本質的にポインタであり、objオブジェクトを作成する関数オブジェクトのprototype属性を指す.
//      
        function Animal(name,age){
            this.name = name;
            this.age= age;
        }
        Animal.prototype = {
            alertName(){
                alert(this.name);
            }
        }
        //    
        var dog = new Animal("  ");
        dog .print = function(){
             alert(this.name);
        }
        dog.print();  //  
        dog.alertName();  //  


print()メソッドはdogインスタンス自体が有するメソッドであるためdog.print()出力「大黄」;AlertName()はdogインスタンスのメソッドではなく、コンストラクション関数のメソッドであるdog.AlertName()は、dogインスタンスがコンストラクション関数のメソッドを継承しているため、「大黄」も出力します.
インスタンスdogの暗黙的なプロトタイプは、その構造関数の明示的なプロトタイプを指し、指向の意味は、すなわち、
dog.__proto__ === Animal.prototype// true

3.コンストラクタconstructor


名前の通り、コンストラクタconstructorは関数オブジェクトを構築するために使用され、constructorプロパティはこのオブジェクトを作成した関数オブジェクトへの参照を返します.通俗的には現在の相手を指すお父さんです
function a(){};
console.log(a.constructor===Function); //true
console.log(a.prototype.constructor===a); //true

関数aはFunctionによって創造され、そのconstructorが指すFunction、a.prototypeはnew a()方式によって創造され、a.prototype.constructorはaを指すべきである.a.prototype._proto_.constructorは誰を指していますか.

4.プロトタイプチェーン


プロトタイプチェーンはJSで継承を実現する主な方法である.その基本思想は、1つの参照タイプに別の参照タイプの属性と方法を継承させることである.
function Animal(){  
    this.animalType = "animal";  
}  
Animal.prototype.getAnimalType = function(){  
    return this.animalType ;  
}  

function Dog(){  
    this.Dogtype = "dog";  
}  
Dog.prototype = new Animal();  

Dog.prototype.getDogType = function(){  
    return this.Dogtype ;  
}  

var dahuang = new Dog();

alert(dahuang.getAnimalType ());// animal
dahuang.getAnimalType ()印刷結果animal,dahuang自体にgetAnimalType ()メソッドがない場合、その_proto_(すなわちそのコンストラクション関数のprototype)に行って探しますが、Dogにもないことがわかり、_proto_に沿ってさらに上を探し、Animal.prototype.getAnimalTypeで見つけて、結果を返します. Animal , , Object.prototype
プロトタイプチェーンとは、オブジェクトに必要な属性またはメソッド参照が見つからない場合、エンジンが[[prototype]]に関連付けられたオブジェクトを検索することである.同様に、後者でも必要な参照が見つからない場合は、上を検索し続けます.Object.prototypeプロトタイプオブジェクトが終了するまで、これがプロトタイプチェーンです.Object.prototypeはプロトタイプチェーンの先端である. Object.prototype , , 。 ,

5.プロトタイプオブジェクトとプロトタイプチェーンの間にはいったいどんな役割がありますか?


コンストラクション関数に多くの属性とメソッドがある場合、コンストラクション関数のすべてのインスタンス化オブジェクトはこれらの属性とメソッドを共通に使用しており、複数のインスタンスがこれらのものを共有したい場合、各インスタンスが1部コピーされると、大きなリソースの浪費をもたらします.それは、これらの共通のプロパティとメソッドを共通のものに保存することを考慮することはできません.この共通のものがプロトタイプオブジェクト(prototype). , 。 , 。 ~