JavaScriptでオブジェクトを作成するスキーマの概要
** JavaScriptはオブジェクトパターンを作成します。
オブジェクトリテラル
工場モデル
コンストラクターモード
プロトタイプモード
コンストラクターとプロトタイプパターンを組み合わせます
プロトタイプの動的モード
**
ほとんどのオブジェクト指向言語には、同じ方法と属性を持つ複数のオブジェクトを作成できるクラスの概念があります。技術的には、JavaScriptはオブジェクト指向の言語ですが、JavaScriptにはクラスの概念がありませんが、すべてはオブジェクトです。任意のオブジェクトは特定の参照タイプのインスタンスであり、既存の参照タイプを介して作成されます。参照タイプは、ネイティブまたはカスタマイズできます。
1。オブジェクトリテラル
var person = {name: 'nicholas';年齢: '22';ジョブ:「ソフトウェアエンジニア」sayname:function(){alter(this.name); }}この例では、名前という名前のオブジェクトが作成され、3つの属性(名前、年齢、ヨブ)とメソッド(SayName())が追加されます。 sayname()メソッドは、this.nameの値を表示するために使用されます(person.nameとして解決されます)。
オブジェクトリテラルを使用して単一のオブジェクトを作成できますが、この方法には明らかな欠点があります。同じインターフェイスを使用して多くのオブジェクトを作成すると、多くの重複コードが生成されます。
2。工場モデル
ファクトリーパターンは、ソフトウェアエンジニアリングの分野でよく知られている設計パターンです。ファクトリーパターンは、特定のオブジェクトを作成するプロセスを抽象化し、関数を使用して、特定のインターフェイスを持つオブジェクトを作成する詳細をカプセル化します。
function createperson(name、age、job){var o = new object {}; o.name = name; o.age = age; o.job = job; o.sayname = function(){alert(this.name); }; return o;} var person1 = creatperson( "nicholas"、22、 "ソフトウェアエンジニア"); var person2 = creatperson( "greg"、24、 "desute");関数CreatePerson {}は、受け入れられたパラメーターに基づいて、必要なすべての情報を含む個人オブジェクトを構築できます。この関数は数え切れない時間と呼ばれ、そのたびに3つのプロパティと1つの方法を含むオブジェクトを返すことができます。
工場モデルは複数の類似のオブジェクトを作成する問題を解決しますが、オブジェクト認識の問題(つまり、オブジェクトのタイプを知る方法)を解決しません。
3。コンストラクターモード
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.sayname = function(){alert(this.name); }} //新しいオペレーターvar person1 = new person( "nicholas"、22、 "ソフトウェアエンジニア"); var person2 = new person( "greg"、24、 "sudent"); person1.sayname(); //nicholasperson2.sayname(); //グレッグ工場モデルとの違いは次のとおりです
表示されていないオブジェクトを作成します
このオブジェクトに属性とメソッドを直接割り当てます
返品声明はありません
人の新しいインスタンスを作成するには、新しいオペレーターを使用する必要があります。コンストラクターを呼び出す4つのステップ:
新しいオブジェクトを作成します
コンストラクターの範囲を新しいオブジェクトに割り当てます(これはこの新しいオブジェクトを指します)
コンストラクターのコードを実行します
新しいオブジェクトを返します
この例で作成されたすべてのオブジェクトは、オブジェクトインスタンスとパーソンインスタンスの両方のインスタンスです。インスタンスオブオペレーターによって検証できます。
alert(person1intanceof object); // true
コンストラクターパターンにも独自の問題があります。実際、SayNameメソッドは各インスタンスで1回再作成されます。インスタンス化によって作成された方法は等しくないことに注意する必要があります。次のコードはそれを証明できます
alert(person1.sayname == person2.sayname); // false
この問題は、グローバル関数としてコンストラクターの外側にメソッドを移動することで解決できます。
function person(name、age、job){this.name = name; this.age = age; this.job = job; } function saysname(){alert(this.name); }グローバルな世界で作成されたグローバルな機能は、実際には人によって作成されたインスタンスによって呼び出すことができますが、これは少し非現実的です。オブジェクトが非常に正しい方法を定義する必要がある場合、多くのグローバル関数を定義する必要がありますが、これにはカプセル化がありません。
4。プロトタイプモード
JavaScriptで作成された各関数には、特定のタイプのすべてのインスタンスで共有できるプロパティとメソッドを含むオブジェクトへのポインタであるプロトタイププロパティがあります(すべてのオブジェクトインスタンスがそのプロパティとメソッドを共有できるようにします)
function person(){} person.prototype.name = "nicholas"; person.prototype.age = 22; person.prototype.job = "ソフトウェアエンジニア"; person.prototype.sayname(){alert(this.name); }; var person1 = new Person(); person1.sayname(); //nicholasalert(person1.sayname == person2.sayname); // true上記のコードはこれらのことをします:
コンストラクターの人を定義します。人間関数は自動的にプロトタイププロパティを取得します。このプロパティには、デフォルトで人を指すコンストラクタープロパティのみが含まれています。
person.prototypeを介して3つのプロパティと1つの方法を追加します
人のインスタンスを作成し、インスタンスでsayname()メソッドを呼び出します
Person constructor and person.prototypeを使用して例としてインスタンスを作成し、オブジェクト間の関係を表示する
Person constructor and person.prototypeを使用して例としてインスタンスを作成し、オブジェクト間の関係を表示する
この図は、個人のコンストラクター、人のプロトタイプの特性、および人の2つのインスタンスとの関係を示しています。 person.prototypeは、プロトタイプオブジェクト、person.prototype.constructorポイントをpersonに戻します。コンストラクター属性を含めることに加えて、プロトタイプオブジェクトには、後で追加された他のプロパティとメソッドも含まれています。両方の人の2つのインスタンスperson1とperson2には内部プロパティが含まれており、person.prototypeのみを指します。
SayName()メソッドの呼び出しプロセス:
person1インスタンスでlogname()メソッドを探しているので、そのような方法がないことがわかりました。
Person1のプロトタイプでSayame()メソッドを探します1。この方法があるので、メソッドは呼び出されます
このような検索プロセスに基づいて、インスタンスのプロトタイプの同名属性を定義することにより、インスタンスがプロトタイプの同じ名前の属性にアクセスするのを防ぐことができます。そうすることは、プロトタイプの同名属性を削除するのではなく、インスタンスがアクセスするのを防ぐだけであることに注意する必要があります。
function person(){} person.prototype.name = "nicholas"; person.prototype.age = 22; person.prototype.job = "ソフトウェアエンジニア"; person.prototype.sayname(){alert(this.name); }; var person1 = new Person(); var person2 = new Person(); person1.name = "greg" alert(person1.name)// gregはインスタンスアラート(person2.name)// nicholasがプロトタイプから来ます削除演算子を使用して、インスタンスプロパティを完全に削除します
person1.name; alert(person1.name)//プロトタイプからnicholasを削除します
hasownProperty()メソッドを使用して、インスタンスまたはプロトタイプでプロパティが存在するかどうかを検出します
function person(){} person.prototype.name = "nicholas"; person.prototype.age = 22; person.prototype.job = "ソフトウェアエンジニア"; person.prototype.sayname(){alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1、hasownproperty( "name")); // false person1.name = "greg" alert(person1.name)// greg from the instance alert(person1、hasownproperty( "name")); person1.name; alert(person1.name)// nicholas from the prototype alert(person1、hasownproperty( "name")); // false次の図は、さまざまな状況でのインスタンスとプロトタイプの関係を示しています
単純なプロトタイプ構文
function person(){} person.prototype = {name: "nicholas"、age:22、job: "software engineer"、sayname:function(){alert(this.name); }};上記のコードでは、コンストラクター属性は人を指し示しなくなり、オブジェクトのタイプをコンストラクターを介して決定することはできません。以下のように適切な値に戻すことができます
function person(){} person.prototype = {constructor:person、name: "nicholas"、age:22、job: "software engineer"、sayname:function(){alert(this.name); }};コンストラクタープロパティをリセットすると、[[[列挙]]]プロパティがTrueに設定されます。デフォルトでは、ネイティブコンストラクタープロパティは列挙できません。 Object.defineProperty()メソッドを使用して変更できます。
object.defineProperty(person.prototype、 "constructor"、{enumerable:false、value:person});プロトタイプで値を見つけるプロセスは検索であり、プロトタイプオブジェクトによって作成された変更は、インスタンスからすぐに反映できます。
var friend = new person(); person.prototype.sayhi = function(){alert( "hi);} friend、sayhi(); //" hi "(問題ありません)Personインスタンスは、新しい方法を追加する前に作成されますが、インスタンスとプロトタイプの間の緩い接続のために、新しく追加された方法にまだアクセスできます
プロトタイプオブジェクトを書き換えた後の状況
function person(){} var friend = new person(); person.prototype = {name: "nicholas"、age:22、job: "software engineer"、sayname:function(){alert(this.name); }}; friend.sayname(); //エラーfriend.sayname()を呼び出すときのエラーの理由は、下の図に示すように、友人によって指摘されたプロトタイプにこのフィールドにちなんで名付けられた属性が含まれていないことです。
プロトタイプオブジェクトの問題
プロトタイプオブジェクトは、コンストラクターの初期化パラメーターを渡すプロセスを省略し、すべての力がデフォルトで同じ属性値を取得します。プロトタイプモデルの最大の問題は、彼らが共有された性質を持っていることです。プロトタイプモデルに参照タイプの属性が含まれている場合、問題はより深刻です。次の例を見てみましょう。
function person()person.pers.prototype = {constructor:person、name: "nicholas"、age:22、job: "ソフトウェアエンジニア"、友人:["shelby"、 "court"]、sayname:function(){alert(this.name); }}; var person1 = new Person(); var person2 = new Person(); person1.friend.push( "van"); Alert(Person1.Friends); // "Shelby、Court、Van" Alert(Person2.Friends);5。コンストラクターモードとプロトタイプモードの組み合わせ
コンストラクターモードとプロトタイプモードの組み合わせで、コンストラクターはインスタンスプロパティを定義するために使用され、プロトタイプモデルはメソッドと共有プロパティを定義するために使用されます。このようにして、各インスタンスにはインスタンス属性の独自のコピーがあり、メソッドへの参照を共有して、メモリを最大限に保存することもできます。
function person(name、age、job){this.name = name; this.age = age; this.job = job; this.friends = ["shelby"、 "court"];} person.prototype = {constructor:person、sayname:function(){alert(this.name); }} var person1 = new Person( "Nicholas"、22、 "Software Engineer"); var person2 = new Person( "Greg"、24、 "Student"); person1.friend.push( "van"); alert(person1.friends); // "Shelby、Court、van" alert(person2.friends); // "Shelby、Court" alert(person1.friends == person2.friends); // false alert(person1.sayname == person2.sayname); // true6.動的プロトタイプモード
プロトタイプの動的モードは、コンストラクターに必要なすべての情報をカプセル化し、IFステートメントを使用して、プロトタイプ内の特定のプロパティが存在するかどうかを判断します。それが存在しない場合(コンストラクターが初めて呼び出された場合)、IFステートメント内でプロトタイプ初期化コードを実行します。
function person(name、age){this.name = name; this.age = age; this.job = job; // method if(typeof this.sayname!= 'function'){person.prototype.sayname = function(){alert(this.name); }; }} var friend = new Person( 'nicholas'、 '22'、 'software engineer'); //コンストラクターは初めて呼び出され、この時点でプロトタイプは変更されました。読書をお勧めします:
JSオブジェクト指向(工場モード、コンストラクターモード、プロトタイプモード)でオブジェクトを作成するいくつかの一般的な方法
上記は、編集者が紹介したJavaScriptでオブジェクトを作成するパターンです。私はそれが誰にでも役立つことを願っています!