JavaScript作成対象の常用方式のまとめ


本論文の実例は、JavaScriptがオブジェクトを作成するための一般的な方法を述べている。皆さんに参考にしてあげます。具体的には以下の通りです。
JSには類の概念がないですが、どうやって対象を作りますか?次に詳しく話します。
従来のオブジェクトの作成方法:
1、Objectを作成する例

var person = new Object();
person.name = "Alice";
person.age = 12;
person.showName = function() {
 alert(this.name);
};

2、対象の字面量形式で単一のオブジェクトを作成する

var person = {
 name : "Alice";
 age : 12;
 showName : function() {
  alert(person.name);
 }
};

オブジェクトを作成する5つのデザインモード
1、工場モード
Objectコンストラクタとオブジェクトの字面の量はすべて単一のオブジェクトを作成するために使用できますが、この方法は明らかな欠点があります。同じインターフェースを使って多くのオブジェクトを作成すると、多くの重複コードが発生します。この問題を解決するために、工場モデルを使い始めました。

function createPerson(name, age) {
 var obj = new Object();
 obj.name = name;
 obj.age = age;
 obj.showName = function() {
  alert(this.name);
 };
 return obj;
}
var person1 = createPerson("Alice", 23);
var person2 = createPerson("Bruce", 22);

2、コンストラクタモード
工場モードは、類似した複数のオブジェクトを作成する問題を解決したが、オブジェクト識別の問題(すなわち、オブジェクトの種類を知らない)を解決しなかったので、コンストラクションモードが現れ、カスタムのコンストラクタは、将来、そのインスタンスを特定のタイプとして識別できることを意味する。これは工場モデルに勝る構造関数モードの場所である。

function Person(name, age) {
 this.name = name;
 this.age = age;
 this.showName = function() {
  alert(this.name);
 };
}
var person1 = new Person("Alice", 23);
var person2 = new Person("Bruce", 22);

コンストラクションモードと工場モードの違いは、
1)オブジェクトを明示的に作成しません。
2)直接属性と方法をthisオブジェクトに付与しました。
3)return文がない
コンストラクタの問題:各方法は各インスタンスで再作成されます。JavaScriptの関数はオブジェクトであるため、関数を定義するごとにFunionオブジェクトを実装しているので、構造関数を使用して作成された各インスタンスはshowName()という方法があるが、これらの方法は同じFunctionの例ではない。異なる例での同名関数は等しくないので、person1.showName == person2.showNameはfalseに戻る。
この問題は、関数の定義を構造関数の外部に移すことで解決できます。

function Person(name,age,job) {
 this.name = name;
 this.age = age;
 this.showName = showName;
}
function showName(){
 alert(this.name);
}
var person1 = new Person("Alice", 23);
var person2 = new Person("Bruce", 22);

このように解決した方法は何度も問題を作っていますが、また新しい問題が出てきました。
(1)グローバルスコープで定義された関数は、実際にはあるオブジェクトにしか呼び出されません。これにより、グローバルドメイン名は副実数ではありません。
(2)オブジェクトが複数の方法を定義する必要がある場合、複数のグローバル関数を定義する必要があるので、パッケージ性は全くない。
これらの問題はプロトタイプモードを用いて解決できる。
3、原型モード
各関数は一つのプロトタイプ属性で、一つのオブジェクトを指します。
プロトタイプオブジェクトを使用する利点は、すべてのオブジェクトインスタンスが、その中に含まれる属性および方法を共有することができることである。つまり、オブジェクトのインスタンスを構造関数で定義する必要はなく、これらの情報を直接プロトタイプオブジェクトに追加することができる。

function Person() {
}
Person.prototype.name = name;
Person.prototype.age = age;
Person.prototype.showName = function(){
 alert(this.name);
};
var person1 = new Person();
var person2 = new Person();

プロトタイプモードを使って作成した新しいオブジェクトは、同じ属性と方法を持っています。構造関数モードとは異なり、これらの属性と方法はすべてのオブジェクトによって共有されます。これは、すべてのインスタンスがデフォルトで同じ属性値を持つことになり、したがって、person1.showName == person2.showNameはtrueに戻る。
あるオブジェクトの属性の検索方法を読み取ります。
1)まずインスタンスで検索し、指定された属性が見つかったら、その属性の値を返します。
2)ポインタが指すプロトタイプのオブジェクトを検索し続けます。
deleteのインスタンス名を使用して、インスタンスの属性を削除します。hasOwnProperty()方法を使用して、属性がインスタンスに存在するか、それともプロトタイプに存在するかを判断することができる。与えられた属性がインスタンスに存在する限り、trueに戻ります。
inオペレータは、オブジェクトを介して指定された属性にアクセスできるときにtrueを返します。この属性がインスタンスに存在するか、プロトタイプに存在するかに関わらず。hasOwnProperty()方法とin操作符を同時に使用して、属性がオブジェクトの中にあるか、それとも原型の中にあるかを決定することができる。

function Person () {
}
Person.prototype.name = "Alice";
Person.prototype.age = "22";
Person.prototype.showName = function(){
 alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name = "Bruce";
alert(person1.name);//Bruce
alert(person1.hasOwnProperty("name"));//true
alert("name" in person1);//true
alert(person2.name);//Alice
delete person1.name;
alert(person1.hasOwnProperty("name"));//false
alert("name" in person1);//true
alert(person1.name);//Alice

プロトタイプの方が簡単な文法:すべての属性と方法を含むオブジェクトの字面量でプロトタイプオブジェクトを作成します。

function Person () {
}
Person.prototype = {
  name:"Alice",
  age : "22",
  showName: function(){
   alert(this.name);
  }
};

オブジェクトの字面量で原型オブジェクトを作成した結果は同じですが、constructor属性はPersonを指しません。これはこのようにすでに完全にデフォルトのプロトタイプオブジェクトを書き換えたので、construct属性は新しいオブジェクトのconstruct属性となり、Objectコンストラクタを指しますが、Person関数を指しません。このとき、instance ofオペレータは、正しい結果を返すことができますが、constructorによっては、オブジェクトのタイプが確定できなくなりました。

var person = new Person();
alert(person instanceof Object);//true
alert(person instanceof Person);//true
alert(person.constructor == Object);//true
alert(person.constructor == Person);//false

construtorの値が重要であれば、わざわざ適切な値に設定することができます。

function Person () {
}
Person.prototype = {
 constructor:Person,
  name:"Alice",
  age : "22",
  showName: function(){
   alert(this.name);
  }
};

プロトタイプオブジェクトは、既存のプロトタイプと以前に存在していたオブジェクトインスタンスとの間の連絡を切断し、オブジェクトインスタンスの参照は依然として最初のプロトタイプである。

function Person () {
}
var person = new Person();
Person.prototype = {
 constructor:Person,
 name:"Alice",
 age : "22",
 showName: function(){
  alert(this.name);
 }
};
person.showName();//  :person.showName is not a function

4、コンストラクタモードとプロトタイプを組み合わせて使う
原型オブジェクトの問題:最大の問題は共有属性によるものです。プロトタイプのすべての属性はインスタンスによって共有されており、これは関数に適切であり、基本値を含む属性についても言えます。しかし、参照値を含む属性については、問題が顕著であり、あるインスタンスの参照タイプを変更する属性も、プロトタイプによって他の例のこの属性に影響を与える。
カスタムタイプを作成する最も一般的な方法は、コンストラクターモードとプロトタイプモードを組み合わせて使用し、コンストラクタモードを使用して、インスタンス属性を定義し、プロトタイプパターンを使用して、方法と共有の属性を定義します。

function Person(name, age) {
 this.name = name;
 this.age = age;
 this.friends = ["Bruce", "Cindy"];
}
Person.prototype = {
 constructor : Person,
 showName : function(){
  alert(this.name);
 }
};
var person1 = new Person("Alice",23);
var person2 = new Person("David",22);
person1.friends.push("Vincy");//        friends
alert(person1.friends);//"Bruce", "Cindy","Vincy"
alert(person2.friends);//"Bruce","Cindy"
alert(person1.friends == person2.friends);//false
alert(person1.showName == person2.showName);//true

5、ダイナミックモデル
動的プロトタイプモードはすべての情報を構造関数にカプセル化し,プロトタイプをコンストラクタに初期化することによって,コンストラクタとプロトタイプを同時に使用する利点を維持した。
プロトタイプを初期化する必要があるかどうかは、あるべき方法が有効かどうかをチェックすることによって決められます。
例えば、showName()方法が存在しない場合にのみ、プロトタイプに追加されます。このコードはコンストラクタの最初の呼び出し時にのみ実行されます。

function Person(name,age) {
 this.name=name;
 this.age=age;
 if(typeof this.showName!="function"){
  Person.prototype.showName=function(){
   alert(this.name);
  }
 }
}
alert(person1.hasOwnProperty("name"));//true

もっと多くのJavaScriptに関する内容に興味がある読者は、当駅のテーマを見ることができます。「javascript対象向け入門教程」、「JavaScriptエラーとデバッグテクニックのまとめ」、「JavaScriptデータ構造とアルゴリズム技術のまとめ」、「JavaScriptはアルゴリズムと技術の総括を遍歴します。」および「JavaScript数学演算の使い方のまとめ
本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。