欠点: オブジェクト認識の問題、つまりオブジェクトのタイプを知る方法は解決されません。
ファクトリ パターンとの比較:
1. 明示的なオブジェクトの作成はありません
2. return ステートメントはありません
2. コンストラクターのスコープを新しいオブジェクトに割り当てます
3.コンストラクター
4. 新しいオブジェクトを返す
コンストラクターの欠点:
各メソッドは各インスタンスで再作成されます。 person1 と person2 の両方にsayName() メソッドがありますが、2 つのメソッドは同じ Function インスタンスではありません。異なるインスタンス上の同じ名前の関数は同等ではありません。 同じタスクを完了する 2 つの Function インスタンスを作成する必要はありません。また、以下に示すように、コードを実行する前に関数を特定のオブジェクトにバインドする必要もありません。 この方法で、sayName 属性をグローバル関数 SayName に設定します。sayName には関数へのポインタが含まれるため、person1 オブジェクトと person2 オブジェクトは同じ関数を共有します。 ただし、オブジェクトで多くのメソッドを定義する必要がある場合は、多くのグローバル関数を定義する必要があり、カスタム参照型のカプセル化はありません。上記の問題を解決するために、プロトタイプモードが導入されました。 3. プロトタイプ パターンプロトタイプ オブジェクトについて理解する
作成するすべての関数には、オブジェクトを指すポインターがあり、このオブジェクトの目的は、表現できるすべてのオブジェクトを含めることです。インスタンスによって共有されるプロパティとメソッド。プロトタイプは、コンストラクターを呼び出すことによって作成されるオブジェクト インスタンスのオブジェクト プロトタイプです。プロトタイプ オブジェクトを使用する利点は、すべてのオブジェクト インスタンスがそれに含まれるプロパティとメソッドを共有できることです。 まず、パーサーはインスタンス person1 に name 属性があるかどうかを尋ね、持っている場合はそれを返します。 そうでない場合は、person1 のプロトタイプで name 属性の検索を続け、存在する場合は戻ります。 そうでない場合は、person1 のプロトタイプのプロトタイプの中から検索を続けます。console.log(Person.prototype.isPrototypeOf(person1)); //true
console.log(Object.getPrototypeOf(person1));
//Person {name: “Yvette”, age: 26, job: “engineer”} 返回的是Person的原型对象。
console.log(Object.getPrototypeOf(person1) === Person.prototype)//true
console.log(Object.getPrototypeOf(person1).name);//”Yvette”
console.log(person1.hasOwnProperty(“name”));//false
in 演算子を使用するには、単独で使用する方法と for-in ループ内で使用する方法の 2 つがあります。 in 演算子を単独で使用すると、指定されたプロパティがインスタンス内にあるかプロトタイプ内にあるかに関係なく、オブジェクトを通じてアクセスできる場合に true を返します。
for in ループを使用して、インスタンス内のプロパティやプロトタイプに存在するプロパティなど、オブジェクトを通じてアクセスできるすべての列挙可能なプロパティを返します。これは、インスタンス内のプロパティがプロトタイプ内の列挙不可能なプロパティをマスクする場合にも返されます。 IE9 より前のバージョンの実装にはバグがあり、列挙不可能な属性をマスクするインスタンス属性は for-in で返されません。
IE9以前のボタンにはログ情報がありません。 person インスタンスの toString() メソッドは、プロトタイプ内の列挙不可能な toString() をブロックしますが、
これにより、 person1.constructor は person を指すのではなく、 Object を指すようになります。コンストラクターが重要な場合は、次のような適切な値に具体的に設定する必要があります:
しかし、このアプローチではコンストラクターのプロパティが列挙可能になります。
列挙不可に設定したい場合(デフォルトは列挙不可)、
Object.defineProperty(Person.prototype, “constructor”, { enumerable: false, value: Person });
を使用できます プロトタイプ内の値を見つけるプロセスは検索であるため、プロトタイプ オブジェクトに加えた変更はすぐにインスタンスに反映されます。 プロトタイプオブジェクト全体を書き直すと、状況は異なります。コンストラクターが呼び出されると、元のプロトタイプへの [[prototype]] ポインターがインスタンスに追加され、プロトタイプを別のオブジェクトに変更することは、コンストラクターと元のプロトタイプの間の接続を切断することと同じです。インスタンス内のポインターは、コンストラクターではなく、プロトタイプのみを指します。 person.prototype は、元のプロトタイプ オブジェクトを指し、新しいプロトタイプ オブジェクトを指しません。 プロトタイプ オブジェクトの問題 プロトタイプ パターンの最大の問題は、その共有される性質によって引き起こされます。 参照型の値を含む属性の場合、問題はさらに顕著です 当初の目的は person1 の友達のみを変更することでしたが、それにより person2 の friends 属性の値も変更されてしまいました。したがって、プロトタイプパターンのみを使用することはほとんどありません。 カスタム タイプを作成する最も一般的な方法は、コンストラクター パターンとプロトタイプ パターンを組み合わせて使用することです。コンストラクター パターンはインスタンス プロパティの定義に使用され、プロトタイプ パターンはメソッドと共有プロパティの定義に使用されます。このように、各インスタンスはインスタンス プロパティの独自のコピーを持ち、メソッドへの参照を共有するため、メモリが最大限に節約されます。 。 上記の方法に加えて、ダイナミックプロトタイプモード、寄生構築モード、ソリッド構築モードもありますが、使用頻度が低いため、詳細は説明しません。
4. コンストラクター パターンとプロトタイプ パターンを組み合わせて使用する
以上がJavaScript でオブジェクトを作成する 4 つの方法 詳細なグラフィカル コードの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。