ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptプロトタイププロパティの詳しい説明
各関数には、オブジェクトへの参照であるプロトタイプ属性があります。このオブジェクトはプロトタイプ オブジェクトと呼ばれます。プロトタイプ オブジェクトには、関数インスタンスによって共有されるメソッドとプロパティが含まれます。つまり、関数はコンストラクター呼び出しとして使用されます (new を使用)。オペレーター呼び出し)、新しく作成されたオブジェクトはプロトタイプ オブジェクトからプロパティとメソッドを継承します。
プライベート変数と関数
プロトタイプについて詳しく話す前に、プロトタイプの設計意図をよりよく理解できるように、関連するいくつかのことについて話しましょう。以前に書いた JavaScript 名前空間のブログでは、JavaScript の関数スコープについて言及しましたが、関数内で定義された変数や関数が外部へのインターフェイスを提供しない場合、それらは外部からアクセスできなくなります。つまり、プライベート変数になります。そしてプライベートな機能。
function Obj(){ var a=0; //私有变量 var fn=function(){ //私有函数 } }
このように、変数 a と関数 fn は関数オブジェクト Obj の外部からはアクセスできなくなり、関数 Obj のインスタンスであってもこれらの変数や関数にはアクセスできなくなります。
var o=new Obj(); console.log(o.a); //undefined console.log(o.fn); //undefined静的変数と関数
function Obj(){ } Obj.a=0; //静态变量 Obj.fn=function(){ //静态函数 } console.log(Obj.a); //0 console.log(typeof Obj.fn); //function var o=new Obj(); console.log(o.a); //undefined console.log(typeof o.fn); //undefinedインスタンス変数、関数
function Obj(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } console.log(typeof Obj.a); //undefined console.log(typeof Obj.fn); //undefined var o=new Obj(); console.log(typeof o.a); //object console.log(typeof o.fn); //functionこれで上記の目的を達成できます
function Obj(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } var o1=new Obj(); o1.a.push(1); o1.fn={}; console.log(o1.a); //[1] console.log(typeof o1.fn); //object var o2=new Obj(); console.log(o2.a); //[] console.log(typeof o2.fn); //function上記のコードの実行結果は完全に期待どおりですが、問題も示しています。と fn は o1 では変更されますが、o2 では変更されません。配列と関数はどちらもオブジェクトであり参照型であるため、o1 のプロパティとメソッドは o2 のプロパティとメソッドと同じ名前を持ちますが、それらは同じであることを意味します。参照ではなく、Obj オブジェクトのコピーによって定義されたプロパティとメソッドへの参照です。 これは属性の問題ではありませんが、メソッドにとっては大きな問題です。メソッドはまったく同じ機能を実行しますが、関数オブジェクトに数千のインスタンス メソッドがある場合、その各インスタンスにはコピーが 2 つ存在するためです。何千ものメソッドのコピーを維持しなければならないのですが、これは明らかに非科学的です。プロトタイプが誕生しました。 prototype
function Person(){ }上の図からわかるように、 person オブジェクトは、prototype 属性を自動的に取得します。また、prototype もオブジェクトであり、 Person オブジェクトを指すコンストラクター属性を自動的に取得します。 インスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプを指す内部ポインター (多くのブラウザーではこのポインターは __proto__ という名前) が含まれます。この接続はインスタンスとコンストラクターのプロトタイプの間に存在します。インスタンスとコンストラクターの間ではありません。
function Person(name){ this.name=name; } Person.prototype.printName=function(){ alert(this.name); } var person1=new Person('Byron'); var person2=new Person('Frank');person インスタンス person1 には name 属性が含まれており、また、Person のプロトタイプを指す __proto__ 属性も自動的に生成され、プロトタイプで定義されている printName メソッドにアクセスできます。おそらく次のようになります。 テストするプログラムを書いて、プロトタイプ内のプロパティとメソッドが共有できるかどうかを確認してください
function Person(name){ this.name=name; } Person.prototype.share=[]; Person.prototype.printName=function(){ alert(this.name); } var person1=new Person('Byron'); var person2=new Person('Frank'); person1.share.push(1); person2.share.push(2); console.log(person2.share); //[1,2]案の定!実際、コードはオブジェクトの属性を読み取るときに、指定された名前の属性から検索を実行します。その属性がインスタンス内で見つかった場合は、その属性が検索されます。そうでない場合は、プロトタイプが検索され、まだ見つからない場合は、再帰後にオブジェクトが見つからない場合は、プロトタイプのオブジェクトを再帰し続けます。同様に、インスタンスにプロトタイプと同名のプロパティや関数が定義されている場合、プロトタイプのプロパティや関数は上書きされます。
function Person(name){ this.name=name; } Person.prototype.share=[]; var person=new Person('Byron'); person.share=0; console.log(person.share); //0而不是prototype中的[]単純なオブジェクトの構築
りー