オブジェクトコンストラクターまたはオブジェクトリテラルを介してオブジェクトを作成するとき、同じインターフェイスを持つ多くのオブジェクトを作成するとき、大量の重複コードが生成されます。簡単にするために、工場モデルが導入されました。
工場モデル
function createperson(name、age、job){var obj = new object(); obj.name = name; obj.age = age; obj.job = job; obj.sayhello(){alert(this.name); }; return obj;} var p1 = createperson( "xxyh"、19、 "programmer"); var p2 = createperson( "zhangsan"、18、 "student");オブジェクトを作成するこの方法はコードを大幅に簡素化しますが、欠点もあります。つまり、オブジェクトのタイプを決定できません。この問題を解決するために、次のパターンが表示されます。
コンストラクターモード
カスタムオブジェクトタイプのプロパティと方法を定義するカスタムコンストラクターを作成します。
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.sayname = function(){alert(this.name); };} var p1 = new person( "xxyh"、19、 "programmer"); var p2 = new person( "jack"、18、 "sudent");上記の例では、person()はcreateperson()を置き換えます。さらに、いくつかの違いがあります。
•表示なしでオブジェクトを作成します。
•このオブジェクトに属性とメソッドを直接割り当てます
•リターンステートメントはありません
個人オブジェクトを作成するには、新しいオペレーターを使用する必要があります。 4つのステップに分かれています。
•新しいオブジェクトを作成します
•コンストラクターの範囲を新しいオブジェクトに割り当てる
•コンストラクターのコードを実行します
•新しいオブジェクトを返します
P1とP2はそれぞれ人のインスタンスを保存します。
アラート(p1.constructor == person); // trueAlert(p2.constructor == person); // 真実
タイプを検出するときにInstanceOFを使用することをお勧めします。
Alert(P1 Instanceof Object); // trueAlert(p1 Instanceof person); // trueAlert(p2 instanceof object); // trueAlert(p2 instanceof person); // trueAlert(p2 instanceof person); // 真実
すべてのオブジェクトがオブジェクトから継承されるため、P1とP2はオブジェクトのインスタンスです。
2.1コンストラクターを関数として扱います
// var person = new person( "xxyh"、19、 "programmer"); person.sayname(); // "xxyh" //通常の関数担当者として使用します( "Zhangsan"、18、 "Student"); // windowwindow.sayname()に追加します。 // "Zhangsan" //別のオブジェクトの範囲でvar objを呼び出しますobj = new object(); person.call(obj、 "jack"、29、 "Manager"); obj.sayname(); //「ジャック」、OBJにはすべてのプロパティとメソッドがあります
2.2コンストラクターの問題
コンストラクターの使用に関する問題は、各インスタンスで各方法を再作成する必要があることです。 P1とP2の両方にSayName()メソッドがありますが、機能のインスタンスではありません。 JavaScriptでは、関数はオブジェクトであるため、関数が定義されるたびにオブジェクトがインスタンス化されます。
コンストラクターは、次のように定義することもできます。
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.sayname = new function( "alert(this.name)");}したがって、異なるインスタンスで同じ名前の関数は等しくありません。
アラート(p1.sayname == p2.sayname); // 間違い
ただし、同じ関数で2つの関数を作成することは冗長であり、コードを実行する前に関数を特定のオブジェクトにバインドする必要はありません。
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.sayname = sayname;} function sayname(){alert(this.name);} var p1 = new person( "xxyh"、19、 "programmer"); var p2 = new person( "jack"、18、 "sudent");上記は、コンストラクターの外側のSayName()の定義を移動し、属性SayNameをコンストラクター内のグローバルSayName関数として設定します。このようにして、SayNameには関数へのポインターが含まれ、P1とP2はグローバル範囲で定義された同じSayName()関数を共有します。
ただし、これには新しい問題があります。グローバルスコープで定義されている関数は、特定のオブジェクトによってのみ呼び出されます。また、オブジェクトが多くのメソッドを定義する場合、参照型はカプセル化を失います。
プロトタイプチェーンモード
各関数にはプロトタイププロパティがあり、オブジェクトを指すポインターです。このオブジェクトの目的は、特定のタイプのすべてのインスタンスで共有できるプロパティと方法を含めることです。プロトタイプは、コンストラクターを呼び出すことによって作成されたそのオブジェクトインスタンスのプロトタイプオブジェクトです。プロトタイプオブジェクトを使用する利点は、すべてのオブジェクトインスタンスが含まれるプロパティとメソッドを共有できることです。これは、コンストラクター内のオブジェクトインスタンスの情報を定義する代わりに、この情報がプロトタイプオブジェクトに追加されることを意味します。
function person(){} person.prototype.name = "xxyh"; person.prototype.age = 19; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person1 = new person(); person1.sayname(); // "xxyh" var person2 = new Person(); person2.sayname(); // "xxyh" alert(person1.sayname == person2.sayname); // 真実3.1プロトタイプオブジェクトの理解
新しい関数を作成するだけで、関数のプロトタイププロパティが作成されます。このプロパティは、関数のプロトタイプオブジェクトを指します。デフォルトでは、すべてのプロトタイプオブジェクトがコンストラクタープロパティを自動的に取得します。このプロパティには、プロトタイププロパティが配置されている関数へのポインターが含まれています。 person.prototype.constructorは人を指します。
インスタンスを作成するためにコンストラクターが呼び出されると、インスタンスの内部には、[[プロトタイプ]]と呼ばれるコンストラクターのプロトタイプオブジェクトへのポインター(内部プロパティ)が含まれます。 Firefox、Safari、Chromeの_Proto経由でアクセスします。この接続は、インスタンスとコンストラクターのプロトタイプオブジェクトの間ではなく、インスタンスとコンストラクターの間ではありません。
次の図は、各オブジェクト間の関係を示しています。
person.prototypeはプロトタイプオブジェクトを指し、person.prototype.constructorポイントをpersonに指します。コンストラクター属性に加えて、プロトタイプに他の追加属性があります。人のインスタンスにはすべて、person.prototypeのみを指す内部プロパティが含まれており、コンストラクターとの直接的な関係はありません。
[[プロトタイプ]]にアクセスすることはできませんが、ISPrototypeof()メソッドを使用して、オブジェクト間にそのような関係があるかどうかを判断できます。
alert(person.prototype.isprototypeof(person1)); // truealert(person.prototype.isprototypeof(person2)); // 真実
オブジェクトのプロパティを読み取るときは、指定された名前の属性の目標とともに、検索が実行されます。検索は、オブジェクトインスタンス自体から始まります。検索は、オブジェクトインスタンス自体から始まります。インスタンスに指定された名前の属性が見つかった場合、属性の値が返されます。発見されていない場合は、ポインターによって指されたプロトタイプオブジェクトを検索し続け、プロトタイプオブジェクトに指定された名前の属性を探します。このプロパティがプロトタイプオブジェクトにある場合、プロパティの値が返されます。
プロトタイプに保存されている値は、オブジェクトインスタンスからアクセスできますが、プロトタイプに保存されている値はオブジェクトインスタンスを介して書き換えることはできません。インスタンスプロトタイプの属性と同じ名前を持つインスタンスに属性を追加すると、属性はプロトタイプの属性をブロックします。
function person()person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person1 = new person(); var person2 = new person(); 「oooo "; alert(person1.name); // "ooooo" alert(person2.name); // "xxyh"上記の例では、Person1の名前属性は、プロトタイプの名前属性をブロックします。
属性がオブジェクトインスタンスに追加されると、この属性は、プロトタイプオブジェクトに保存された同じ名前の属性をブロックします。これは、このプロパティの存在がプロトタイプ内のそのプロパティへのアクセスを妨げることを意味します。 deleteを使用して、インスタンスプロパティを削除します。
function person()person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person1 = new person(); var person2 = new person(); 「oooo "; alert(person1.name); // "ooooo" alert(person2.name); // "xxyh" delete person1.name; alert(person1.name); // "xxyh"hasownProperty()は、インスタンスまたはプロトタイプにプロパティが存在するかどうかを検出できます。
function person()person.prototype.name = "xxyh"; person.per.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person1 = new person person(); alert(person1.hasownproperty( "name")); // falsePerson1.name = "oooo"; alert(person1.hasownproperty( "name")); // 真実次の図は、さまざまな状況での実装とプロトタイプの関係を示しています。
3.2プロトタイプおよびオペレーター
in operatorを使用する方法:for-inループで単独で使用します。単独で使用すると、インスタンスまたはプロトタイプに存在するかどうかにかかわらず、オブジェクトを介して特定のプロパティにアクセスするときに、オペレータはtrueを返します。
function person(){} person.prototype.name = "xxyh"; person.per.age.age.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person1 = new person(); // trueperson1.name = "oooo"; alert( "name" in person1); // 真実以前のhasownProperty()機能と組み合わせることで、プロパティがプロトタイプ内のプロパティまたはインスタンスのプロパティであると判断できます。 in operatorがtrueを返し、Hasownpropertyがfalseを返す場合、プロパティはプロトタイプのプロパティです。
関数hasprototypeproperty(object、name){return!object.hasownproperty(name)&&(name in object);}次に、hasprototypeproperty()の使用法を見てみましょう。
function person(){} person.prototype.name = "xxyh"; person.per.age.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var person = new person(); // trueperson.name = "oooo"; alert(hasprototypeproperty(iners、 "name")); // 間違いfor-inループを使用する場合、インスタンス内のプロパティやプロトタイプのプロパティなど、オブジェクトからアクセスできるすべての列挙可能なプロパティ。プロトタイプ内の承認できないデータをブロックするインスタンス属性(つまり、[[[列挙]]]によって偽としてマークされた属性)も、開発者によって定義されるすべての属性が誘導可能であるため、フォーインで返されます。
オブジェクト上のすべての列挙可能なインスタンスプロパティを取得するには、object.keys()メソッドを使用できます。
function person(){} person.prototype.name = "xxyh"; person.pertotype.age.age.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function(){alert(this.name);}; var keys = objecy.keys(person.prototype); alert(key); // name、age、job、saynamevar p1 = new person(); p1.name = "ooooo"; p1.age = 15; var p1_keys = object.keys(p1); alert(p1_keys); //名前、年齢すべてのインスタンスプロパティを取得する必要がある場合は、object.getownPropertyNames()メソッドを使用できます。
var keys = object.getownPropertynames(person.prototype); alert(keys); //「コンストラクター、名前、年齢、ヨブ、SayName」
3.3よりシンプルなプロトタイプ構文
入力を合理化するには、統合されたプロトタイプオブジェクトを、すべてのプロパティとメソッドを含むオブジェクトリテラルをオーバーライドします。
function person(){} person.prototype = {name: "xxyh"、age:18、job: "programmer"、sayname:function(){alert(this.name); }};上記は、Person.prototypeをオブジェクトリテラル形式で作成した新しいオブジェクトに等しくなります。結果は同じですが、コンストラクター属性はもはや人を指していません。
正しい結果はInstanceOFから返すことができますが、コンストラクターはオブジェクトのタイプを決定できません。
var boy = new person(); alert(boy instanceof object); // TrueALERT(Boy InstanceOf Person); // truealert(boy.constructor == person); // falsealert(boy.constructor == object); // 真実
コンストラクターの値は、次の方法で設定できます。
function person(){} person.prototype = {constructor:person、name: "xxyh"、age:18、job: "programmer"、sayname:function(){alert(this.name); }};3.4プロトタイプチェーンの動的
プロトタイプ内の値を見つけるプロセスは検索であるため、プロトタイプオブジェクトに加えられた変更はインスタンスに反映されます。ただし、プロトタイプオブジェクト全体が書き換えられると、結果は異なります。コンストラクターを呼び出すと、[[プロトタイプ]]元のプロトタイプへのポインターがインスタンスに追加され、プロトタイプを別のオブジェクトに変更することは、コンストラクターと元のプロトタイプ間の接続を切り取ることに相当します。インスタンスのポインターは、コンストラクターではなく、プロトタイプのみを指します。
function person(){} var boy = new person(); person.prototype = {constructor:person、name: "xxyh"、age:29、job: "programmer"、sayname:function(){alert(this.name); }}; boy.sayname(); // エラー特定のプロセスは次のとおりです。
上からわかるように、プロトタイプオブジェクトの書き換えは、既存のプロトタイプと以前に既存のオブジェクトインスタンスとの間の接続を切り取ります。彼らは元のプロトタイプを指します。
3.5ネイティブオブジェクトのプロトタイプ
すべてのネイティブリファレンスタイプは、コンストラクターのプロトタイプのメソッドを定義します。ネイティブオブジェクトのプロトタイプを通じて、デフォルトの方法を取得できるだけでなく、新しい方法も定義できます。
string.prototype.startswith = function(text){return this.indexof(text)== 0;}; var msg = "Good Morning"; alert(msg.startswith( "good")); // 真実3.6プロトタイプオブジェクトの問題
プロトタイプパターンには2つの問題があります。
•デフォルトではすべて同じ属性値。
•プロトタイプ内のすべての属性は、インスタンスによって共有されます
以下の例を見てみましょう。
function person(){} person.prototype = {constructor:person、name: "xxyh"、age:18、job: "programmer"、friends:["zhang san"、 "li si"]、sayname:function(){alert(this.name); }}; var p1 = new person(); var p2 = new person(); p1.friends.push( "wang wu"); alert(p1.friends); // Zhang San、Li SI、Wang Wu Alert(P2.Friends); // Zhang San、Li SI、Wang Wu Alert(p1.friends == p2.friends); // 真実P1.Friendsを介して上にアイテムが追加されました。 Friendsアレイは個人的に存在するため、プロトタイプでは、P2.Friendsにも反映されます。ただし、インスタンスには通常、すべての属性があります。
コンストラクターモードとプロトタイプモードを組み合わせて使用します
コンストラクターモードは、インスタンスプロパティを定義するために使用され、プロトタイプモードはメソッドと共有プロパティを定義するために使用されます。このようにして、各インスタンスにはインスタンス属性の独自のコピーがありますが、同時にメソッドへの参照を共有します。
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.friends = ["zhang san"、 "li si"];} person.prototype = {constructor:person、sayname:function(){alert(this.name); }} var p1 = new Person( "Xiao Xiao Yihan"、18、 "Programmer"); var p2 = new person( "kuiba"、10、 "Monster Hunt"); p1.friends.push( "wang wu"); alert(p1.friends); // Zhang San、Li SI、Wang Wu's Alert(P2.Friends); // Zhang San、Li Si Alert(p1.friends == p2.friends); // falsealSealert(p1.sayname == p2.sayname); // 真実上記の例では、インスタンスプロパティはコンストラクターで定義され、共有プロパティコンストラクターとメソッドSayName()はプロトタイプで定義されます。 P1.Friendsの変更は、P2.Friendsの結果に影響しません。
動的プロトタイプモード
動的プロトタイプパターンは、コンストラクターのすべての情報をカプセル化し、コンストラクターのプロトタイプを初期化することにより、コンストラクターとプロトタイプの両方を使用する利点を維持します。つまり、存在するべき方法が効果的かどうかを確認して、プロトタイプを初期化する必要があるかどうかを判断することが可能です。
function person(name、age、job){// property this.name = name; this.age = age; this.job = job; // method if(typeof this.sayname!= "function"){person.prototype.sayname = function(){alert(this.name); }}}これは、Sayname()メソッドが存在しない場合にのみプロトタイプに追加され、コンストラクターが初めて呼び出された場合にのみ実行されます。
寄生コンストラクタパターン
このパターンのアイデアは、オブジェクトを作成するコードをカプセル化して、新しく作成したオブジェクトを返す関数を作成する関数を作成することです。
function person(name、age){var obj = new object(); obj.name = name; obj.age = age; obj.sayname = function(){alert(this.name); } return obj;} var boy = new person( "xxyh"、19、 "programmer"); boy.sayname();それは注意する必要があります:まず第一に、返されたオブジェクトはコンストラクターまたはコンストラクターのプロトタイプ属性と関係がありません。コンストラクターによって返されるオブジェクトは、コンストラクターの外側で作成されたオブジェクトと変わりません。オブジェクトタイプを決定するために依存することはできません。
安定したコンストラクターパターン
安全なオブジェクトは、公共の属性がないオブジェクトを指し、その方法はこれを参照しません。安定したコンストラクターは、寄生コンストラクターと同様のパターンに従いますが、2つの違いがあります。
•新しく作成されたオブジェクトのインスタンスメソッドは、これを参照しません。
•コンストラクターは、新しいオペレーターを使用して呼び出されません
次のように、その人のコンストラクターを書き直します。
function person(name、age、job){var obj = new object(); obj.sayname = function(){alert(name); }; OBJを返します;} function person(name、age、job){var obj = new object(); obj.sayname = function(){alert(name); }; OBJを返します;}上記の記事は、JavaScriptオブジェクトの作成について簡単に説明しています。私があなたと共有するすべてのコンテンツです。私はそれがあなたに参照を与えることができることを願っています、そしてあなたがwulin.comをもっとサポートできることを願っています。