Javascript -- OO

5613 ワード

scriptではクラスを作成できないので、構造関数でクラスの定義を行うしかありません.属性や方法があります.
ファクトリモードファクトリモード:単純な関数を使用してオブジェクトを作成し、オブジェクトに属性とメソッドを追加し、オブジェクトに戻り、最後にコンストラクション関数に置き換えられます.
コンストラクション関数:カスタムリファレンスタイプを作成したり、組み込みオブジェクトインスタンスを作成するようにnewオペレータを使用したりできます.ただし、コンストラクション関数モードには、各メンバーが新しいインスタンスで再作成されるという欠点もあります.関数は、任意のオブジェクトに限定されないため、複数のオブジェクトキーで関数を共有しない理由はありません.共有として定義し、メンバーメソッドでthisを参照することができます.
プロトタイプモード:コンストラクション関数のprototypeプロパティを使用して、共有すべきプロパティとメソッドを指定します.コンストラクション関数モードとプロトタイプモードを組み合わせるには、コンストラクション関数を使用してインスタンス属性を定義し、プロトタイプを使用して共有する属性と方法を定義します.
Javascriptは主にプロトタイプチェーンによって継承され、プロトタイプチェーンの構築は、あるタイプのインスタンスを別の構造関数のプロトタイプに割り当てることによって実現される.これにより、サブタイプは、クラスベースの継承と同様に、スーパータイプのすべての属性とメソッドにアクセスできます.プロトタイプチェーンの問題は、オブジェクトインスタンスが継承されたすべてのプロパティとメソッドを共有するため、単独で使用するのは適切ではありません.この問題を解決する技術は,サブタイプ構造関数の内部でスーパータイプ構造関数を呼び出す構造関数を借りることである.これにより、各インスタンスに独自のプロパティを持つことができます.また、コンストラクション関数モードのみを使用してタイプを定義することも保証されます.最も多く使用される継承モードは、プロトタイプチェーンを使用して共有された属性とメソッドを継承し、コンストラクション関数を借りてインスタンス属性を継承する組合せモードです.
プロトタイプ継承は,構造関数を予め定義する必要がなく継承を実現することができ,その本質は与えられたオブジェクトに対する浅い複製を実行することであり,複製されたコピーはさらに改造することができる.
寄生継承は、プロトタイプ継承と同様に、オブジェクトまたはいくつかの情報に基づいてオブジェクトを作成し、オブジェクトを強化し、最後にオブジェクトを返します.組合せ継承モードが複数のスーパータイプ構造関数を呼び出すことによる低効率の問題を解決するために.
寄生コンビネーション継承、セット寄生式継承とコンビネーション継承の利点と一体は、タイプベース継承を実現する最も有効な方法である.
オブジェクトにはconstructor(コンストラクション関数)プロパティがあります.この属性はpersonを実行する.オブジェクトタイプを識別するために最初に使用されましたが、カスタムタイプを識別するためにinstanceofオペレータを使用することが望ましいようになりました.これも、ファクトリモードの代わりにコンストラクション関数を使用する理由です.
alert(person1.constructor == Person);        //true
alert(person1 instanceof Person);            //true

コンストラクション関数を関数とする
コンストラクション関数とは、関数をnew呼び出したことです.そうでなければ普通の関数と同じです
//     
var Person = new Person("ali", 29, "home");
person.sayname();                           //ali

//             
var o = new Object();
Person.call(o, "lily", 27, "company");      //  call o,  Person  ,    this.name    ,   o       
o.sayname();                                //lily 

各関数にはprototypeプロパティがあり、カスタムの特定のタイプのすべてのインスタンスが共有するプロパティとメソッドを含むprototypeオブジェクトを指します.最初はconstructorプロパティのみがこのオブジェクトに含まれます.コンストラクション関数自体を指すので、私たちはこの方法にアクセスすることができます.
各オブジェクトのインスタンスにはプロパティがあります.proto_をクリックして、コンストラクション関数オブジェクト内のprototypeが指すオブジェクトを指します.prototypeは共有されているため、これはすべてのインスタンスにとって使用されることに注意してください.
コンストラクション関数はprototypeがオブジェクトを指す部分に関係なくthis参照操作を行う論理である.prototypeのconstructorプロパティは現在の関数を指すので、コンストラクション関数を指すと言います.
アクセス順:prototypeが指すプロトタイプオブジェクトで検索する前に、インスタンスに名前があるかどうかを確認します.
Person.name = "ali";                        //           
Person.prototype.name = "ali";              //                

hasownproperty()メソッドとinオペレータにより、このプロパティがインスタンスに存在するか、プロトタイプに存在するかを決定できます.
alert("name" in Person1);                   //  true  ,       ,        。
alert(person1.hasOwnProperty("name"));      //     ,        ,      
プロトタイプのダイナミック:プロトタイプオブジェクトの変更は、インスタンスにすぐに表示されます.
エラーポイント:var person=new Person()オブジェクトを定義し、関数Personのprototypeオブジェクトを書き換えると、書き換える前のオブジェクトは元のプロトタイプオブジェクトを参照します.前に述べたように、各オブジェクトの作成には属性があります.proto_プロトタイプオブジェクトを指し、関数のprototypeを書き換えると、新しい関数prototypeは新しい位置を指し、以前のオブジェクトには影響しません.
コンストラクション関数とプロトタイプモードの例を組み合わせて、コンストラクション関数モードはインスタンスのプロパティを定義し、プロトタイプモードはメソッドと共有のプロパティを定義します.これは、現在最も広く使用されているカスタムタイプを作成する方法です.
function Person(name, age, job){
    //  
    this.name = name;
    this.job  = job;
    this.age  = age;
    this.friends = ["ali", "lily"];             //    ,           

    //  
    if (typeof this.sayname != "function"){     //               ,         ,      if      
	Person.prototype.sayname = function(){
	    alert(this.name);
	};
    }
}

継承
プロトタイプチェーンは継承を実現する主な方法として、プロトタイプオブジェクトを先に書き換え、別のタイプのインスタンスを付与することによって、現在のプロトタイプオブジェクトが別のオブジェクトのプロトタイプオブジェクトにアクセスできると同時に、別のオブジェクトがプロトタイプオブジェクトのconstructorプロパティを介して現在のオブジェクトの構造方法にアクセスできるようになります.次に、このオブジェクトのプロトタイプオブジェクトが別のオブジェクトを指す場合、チェーン構造を構成します.
まず、現在のオブジェクトのプロトタイプオブジェクトを書き換えてから、このプロトタイプオブジェクトの機能を追加する必要があります.
プロトタイプチェーンの問題:親インスタンスのすべてのプロパティとメソッドが、サブ関数のプロトタイプオブジェクトのプロパティになります.
function SuperType(name){
    this.name = name;
    this.color = ["red","blue"];
}
SuperType.prototype.sayname = function(){
    alert(this.name);
};

function SubType(name, age){
    SuperType.call(this, name);            //     Supertype()       ,                    name,color。
    this.age = age;
}

SubType.prototype = new SuperType();       //     Supertype(),   name,color    sayname   prototype 

SubType.prototype.sayage = function(){
    alert(this.age);
};

実際には2回のSupertype()を呼び出す構造方法であり,実際には複数回の呼び出しも非常に時間がかかることが分かったはずである.次に、寄生コンビネーションモードの継承を改善します.
function inherit(SubType, SuperType){
    var prototype = Object(SuperType.prototype);  //    ,
    prototype.constructor = SubType;              //          
    SubType.prototype = prototype;          //                         ,                 constructor
}

function SuperType(name){
    this.name = name;
    this.color = ["red","blue"];
}
SuperType.prototype.sayname = function(){
    alert(this.name);
};

function SubType(name, age){
    SuperType.call(this, name);            
    this.age = age;
}

inherit(SubType,SuperType);               //            。。。。。    

SubType.prototype.sayage = function(){
    alert(this.age);
};

注意:Jsではクラスを定義する属性を実装する必要はありません.属性に値を割り当てるだけで、jsは自動的にこれらの属性を作成します.
詳しくは:Javascript高度なプログラミング、第6章オブジェクト向けのプログラム設計