1. 関数(コンストラクター)、プロトタイプ、インスタンスオブジェクトの関係
A. 関数とプロトタイプの関係
1. 関数は、作成される限り、特定のセットに従って作成されます。ルールのプロトタイプ属性 (プロトタイプ オブジェクト)
例:
function fun(){
}
console.log(fun.prototype) //fun {}、プロトタイプがオブジェクトであることを示します
注: 属性とプロトタイプで定義されたメソッド。これは、コンストラクターを呼び出すすべてのインスタンス化されたオブジェクトによって共有されます。 2. プロトタイプ属性は、コンストラクター (constructor) 属性を自動的に取得します。コンストラクター属性には、プロトタイプ属性が配置されている関数 (fun) のポインターが含まれます。 (非常に重要)、コンストラクター (楽しい) でプロトタイプで定義されたプロパティとメソッドにアクセスできることを示します。
function fun(name){
console.log() fun.prototype.name == this.name); //true(yjh)
this.name = "yjh1";
console.log(this.name);//yjh1
console.log(fun.prototype.name) == this.name);//false(yjh ,yjh1)
}
fun.prototype = {
コンストラクター: fun,
名前: "yjh"
}
var fun1 = new fun();
console.log( fun.prototype.constructor == fun); // true
console.log(fun1.constructor == fun); // true
B. 関数が new を使用する場合演算子を使用してオブジェクトをインスタンス化すると、そのオブジェクトにはプロトタイプを指す組み込み __proto__ 属性が含まれます。この属性は、インスタンス オブジェクトとプロトタイプ オブジェクトの間にのみ存在します。 例:
this.name = name。 ;
this.age = age; this.SayName = Function () {
Alert (this.Name); }
var fun1 = new fun("yjh","23");
console。 log(fun1.__proto__) //fun { age="22",sayAge=function()}
console.log(fun1 .__proto__ == fun.prototype); //true
C.関数 (コンストラクター)
1. 関数が new 演算子を使用してオブジェクトをインスタンス化すると、インスタンス オブジェクトは内部属性 __proto__ ポイントをプロトタイプに渡し、プロトタイプのコンストラクター プロパティとして定義されたプロパティとメソッドを共有します。コンストラクターを指す場合、インスタンス オブジェクトにはコンストラクターで定義されたプロパティとメソッドも含まれます。例:
function fun(name ,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var fun1 = new fun("yjh", "23");
fun1.sayName(); //yjh
D。 (コンストラクター)、インスタンス オブジェクト、およびプロトタイプ
fun1.age = 24;
fun1.sayAge(); //24、プロトタイプ内のメソッドが呼び出されます;
まず、sayAge メソッドを検索します。インスタンス オブジェクト内に見つからない場合は、プロトタイプを検索し、プロトタイプ内でsayName メソッドを見つけ、age 属性の検索を続けます。そして、age 値が fun1 インスタンス オブジェクトに定義されていることが判明したため、検索を続行せずに直接使用します。 ; age 属性が fun1 インスタンス オブジェクトで直接定義されていない場合、結果は 23 になります。その理由は、コンストラクターがインスタンス オブジェクトの age 属性を再定義するためです
______________________________________________________
2. オブジェクト指向モード:
関数の初期理解:
a. JavaScript の関数は関数型のインスタンスであり、関数関数が定義されている場合、それはオブジェクトです。 、インスタンス オブジェクトの内部属性 __proto__ は Object コンストラクターのプロトタイプ属性を指すため、インスタンスは Object オブジェクトのデフォルトの属性とメソッドを継承します。
b. 通常の関数はデフォルトで未定義を返し、コンストラクターはインスタンス オブジェクトを返します。 。
1. オブジェクトを作成するには、特定のインターフェイス new Object() を使用します
欠点: 同じインターフェイスを使用して多数のオブジェクトを作成すると、大量の繰り返しコードが生成されます
2. ファクトリ パターンを使用し、関数でカプセル化します。特定のインターフェイスを使用してオブジェクトを作成します
例:
function createObj(name,age){
var o = new Object();
o.name = name;
o.age = age;
return o;
}
var o1 = createObj("yjh" ,23)
利点: インターフェイスを使用して複数の同様のオブジェクトを作成し、大量の重複コードを生成する問題を解決します
欠点: オブジェクト認識の問題、つまり、オブジェクト型 o1 の種類は
3. コンストラクター パターン、JavaScript 例:
function CreateObj(name,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert("hi" + this.name);
}
}
var obj1 = new CreateObj("yjh1",23);
var obj2 = new CreateObj("yjh2",23);
利点: インスタンスのオブジェクト タイプ識別の問題を解決します。obj1、obj2 オブジェクトは CreateObj Type www.2cto.com
欠点: コンストラクターによって定義されたプロパティとメソッドはすべてのインスタンスで共有されません。各インスタンスによって呼び出されるメソッドは 2 つのインスタンスです。異なる関数タイプ (obj1.sayName != obj2.sayName)
例:
function CreateObj(){
}
CreateObj.prototype = {
constructor: CreateObj,
name: "yjh",
年齢: 23,
colors: ["a","b"],
sayName: function(){
alert(this.name);
}
}
var obj1 = new CreateObj();
var obj2 = new CreateObj();
alert(obj1.sayName == obj2.sayName);/ /true
obj1.colors.push("c");
alert(obj2.colors);//a,b,c
メモ: obj1 および obj2 インスタンスのプロパティとメソッドを呼び出すと、インスタンス自体によって定義されたプロパティが最初に検索され、インスタンスの __proto__ 内部属性がプロトタイプを指しているため、メソッドが検索されない場合は、
検索が継続されます。プロトタイプで定義された属性とメソッド
欠点: プロトタイプで定義されたプロパティに参照型の値が含まれる場合1 つのインスタンス プロパティの値を変更すると、別のインスタンス プロパティの値に影響します。これは、プロトタイプの共有の性質によるものです。その結果、結合モード (コンストラクター モードとプロトタイプ モード)
など:
console.log(this.name);//yjhyjh
this.name = name;
this.age = age;
this.colors = ["a","b"];
}
CreateObj.prototype = {
コンストラクター: CreateObj,
name: "yjhyjh",
sayName: function(){
return this.name;
}
}
var obj1 = new CreateObj("yjh1",23);
var obj2 = new CreateObj("yjh2",23);
alert(obj1.sayName == obj2.sayName);/ /true
alert(obj1.sayName());//yjh1
alert(obj2.sayName() );//yjh2
obj1.colors.push("c");
alert(obj2.colors);// a, b
説明: コンストラクター内のすべてのインスタンスで共有する必要のないプロパティを定義します。プロトタイプで共有する必要があるプロパティとメソッドを定義します。 補完コンストラクター パターンとプロトタイプ パターンの長所と短所
プロトタイプはすべてインスタンス化されたオブジェクトです プロトタイプ オブジェクト、インスタンス、プロトタイプはプロトタイプに接続されます。インスタンスの内部属性 __proto__ を通じて、すべてのインスタンスがプロトタイプ内の属性とメソッドを共有します。コンストラクターがプロトタイプ内で同じ名前の属性とメソッドを再定義すると、インスタンス オブジェクトのコンストラクターで定義されたプロパティとメソッドが呼び出されます。
6. 継承 (実装継承、プロトタイプチェーン)
は、あるコンストラクターのプロトタイプを別のコンストラクターのインスタンス化されたオブジェクトとして使用することです。このインスタンス化されたプロトタイプ オブジェクトは、他のコンストラクターのプロトタイプの属性とメソッドを継承します。
function Fun1(){
this.name = ["yjh1","yjh2"];
}
Fun1.prototype = {
constructor: Fun1,
sayName: function(){
alertなどのプロトタイプチェーン
と呼ばれます(this.name)
}
}
function Fun2(){}
Fun2.prototype = new Fun1();
var fun2 = new Fun2();
fun2.sayName();//yjh1,yjh2
fun2。 name.push("yjh3"); //fun2.name = ["yjh1","yjh2","yjh3"];
var fun3 = new Fun2();
alert(fun3.name);//yjh1, yjh2、yjh3
短所: 参照型の値を含むプロトタイプから、プロトタイプで定義されたプロパティとメソッドはすべてのインスタンスで共有されます。Fun2.prototype プロトタイプ オブジェクトは Fun1 型のインスタンスです。
そのため、プロトタイプ オブジェクトには参照型が含まれます値 name 属性。複数の Fun2 タイプのオブジェクトをインスタンス化する場合、すべてのインスタンス オブジェクトはプロトタイプの name 属性を共有します。インスタンス内の name 属性の値を変更することで、
はプロトタイプで定義された name 属性の値を直接変更します。 7. 組み合わせの継承 (継承コンストラクターと借用コンストラクター)
function Fun1(){
this.name = ["yjh1","yjh2"];
}
Fun1.prototype = {
constructor: Fun1,
sayName: function( ; . SayName();//yjh1,yjh2
fun2.name.push("yjh3"); //fun2.name = ["yjh1","yjh2","yjh3"];
var fun3 = new Fun2() ;
alert(fun2.name);//yjh1,yjh2,yjh3
alert(fun3.name);//yjh1,yjh2
注: コンストラクターで定義された属性のため、メソッドはすべてのインスタンスで共有されるわけではなく、プロトタイプで定義されたプロパティとメソッドはオーバーライドされるため、インスタンス化されたプロトタイプ オブジェクト (Fun2.prototype) に参照型値を持つプロパティが含まれているために問題が発生することはありません