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