ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript プロトタイプの使用の概要_javascript スキル

JavaScript プロトタイプの使用の概要_javascript スキル

WBOY
WBOYオリジナル
2016-05-16 17:24:12878ブラウズ

JavaScript を使用したことのある学生はプロトタイプに精通しているはずですが、初心者は関数にプロトタイプ属性があり、アクセスなどの関数を追加できることしか知りません。最近、いくつかの高度な JavaScript プログラミングを検討し、ついにその謎を明らかにしました。

各関数には、オブジェクトへの参照であるプロトタイプ属性があります。このオブジェクトはプロトタイプ オブジェクトと呼ばれます。プロトタイプ オブジェクトには、関数インスタンスによって共有されるメソッドとプロパティが含まれます。これは、関数がコンストラクター呼び出しとして使用されることを意味します。 new 演算子を使用して呼び出すと、新しく作成されたオブジェクトはプロトタイプ オブジェクトからプロパティとメソッドを継承します。

プライベート変数と関数

プロトタイプについて詳しく話す前に、プロトタイプの設計意図をよりよく理解できるように、関連するいくつかのことについて話しましょう。以前の JavaScript 名前空間 の記事では、関数内で定義された変数と関数が外部の世界へのインターフェイスを提供しない場合、つまり、外部の世界からアクセスできなくなります。それらはプライベート変数とプライベート関数になります。

コードをコピー コードは次のとおりです:

function Obj(){
var a=0 ; //プライベート変数
var fn=function(){ //プライベート関数

}
}

このように、変数 a と関数 fn は関数オブジェクト Obj の外部ではアクセスできません。これらはプライベートになり、関数 Obj のインスタンスでもこれらの変数と関数にアクセスできなくなります。

コードをコピー コードは次のとおりです。

var o=new Obj();
console .log(o.a); //未定義
console.log(o.fn); // 未定義

静的変数、関数

関数が定義され、「.」で追加された属性と関数はオブジェクト自体からアクセスできますが、そのインスタンスにはアクセスできない場合、そのような変数と関数はそれぞれ静的変数と静的関数と呼ばれます。 Java と C# を使用すると、static の意味が簡単に理解できます。

コードをコピー コードは次のとおりです。

function Obj(){



Obj.a=0; //静的変数

Obj.fn=function(){ //静的関数

}

コンソール.log (Obj.a); / /未定義
console.log(typeof o.fn); //未定義




インスタンス変数、関数

オブジェクト指向プログラミングでは、いくつかのライブラリ関数に加えて、オブジェクトの定義時にいくつかのプロパティとメソッドを定義することが望まれます。これらはインスタンス化後にアクセスできます。

コードをコピー

コードは次のとおりです:

function Obj(){
this.a=[]; //インスタンス変数
this.fn=function(){ //インスタンスメソッド

}
}

console.log(typeof Obj.a); //未定義
console.log(typeof Obj.fn); //未定義

var o=new Obj();
console.log(typeof o.a); //object
console.log(typeof o.fn); // 関数

これでも上記の目的は達成できますが、

コードをコピー コードは次のとおりです:

function Obj(){
this .a= []; //インスタンス変数
this.fn=function(){ //インスタンスメソッド

}
}

var o1=new Obj();
o1.a.push(1);
o1.a.push(1) ); /object
var o2=new Obj();
console.log(o2.a); /[]
console.log(typeof o2.fn) //関数


;
上記のコードの実行結果は完全に期待どおりですが、a と fn は o1 で変更されていますが、配列と関数はどちらもオブジェクトであり参照型であるため、問題も示されています。これは、o1 のプロパティとメソッドは o2 のものと同じ名前ですが、それらは参照ではなく、Obj オブジェクトによって定義されたプロパティとメソッドのコピーであることを意味します。

これは属性にとっては問題ではありませんが、メソッドにとっては大きな問題です。メソッドはまったく同じ機能を実行しますが、関数オブジェクトに 1000 のメソッドとインスタンスのメソッドがある場合、それぞれのインスタンスが 2 回コピーされるからです。何千ものメソッドのコピーを維持する必要がありますが、これは明らかに非科学的です。プロトタイプが誕生しました。

プロトタイプ

新しい関数が作成されると、特定のルールに従ってその関数のプロトタイプ属性が作成されます。デフォルトでは、この属性は関数へのポインターです。プロトタイプ属性が配置されている場所は少し複雑です。コードを書いて上の図を見てください。

コードをコピーします コードは次のとおりです:
function Person(){






image上の図からわかるように、Person オブジェクトは、prototype 属性を自動的に取得します。また、prototype もオブジェクトであり、Person オブジェクトを指すコンストラクター属性を自動的に取得します。

インスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプを指す内部ポインター (多くのブラウザーではこのポインターの名前は __proto__ です) が含まれます。この接続はインスタンスとプロトタイプの間に存在します。インスタンスとコンストラクターの間ではなく、コンストラクターです。

コードをコピー コードは次のとおりです:

function Person(name){
this.name=name;
}

Person.prototype.printName=function(){
alert( this.name) ;
}

var person1=新しい人物('バイロン');
var person2=新しい人物('フランク');

image

person インスタンス person1 には name 属性が含まれており、自動的に __proto__ 属性を生成します。これは Person のプロトタイプを指し、プロトタイプで定義されている printName メソッドにアクセスできます。これは次のようになります。

image

プロトタイプ内の属性とメソッドを共有できるかどうかをテストするプログラムを作成して確認します

コードをコピー コードは次のとおりです:

function Person(name){
this.name =name;
}

person.prototype.share=[];

Person.prototype.printName=function(){
alert(this.name) ;
}

var person1=新しい人物('バイロン');
var person2=新しい人物('フランク');

person1.share.push(1) ;
person2.share.push(2);
予想通り!実際、コードはオブジェクトの属性を読み取るときに、指定された名前の属性から検索を実行します。その属性がインスタンス内で見つかった場合は、その属性が検索されます。見つからない場合はプロトタイプが検索され、それでも見つからない場合は、再帰後にオブジェクトが見つからない場合は、プロトタイプのオブジェクトを再帰し続けます。 。同様に、インスタンスにプロトタイプと同名のプロパティや関数が定義されている場合、プロトタイプのプロパティや関数は上書きされます。

コードをコピー

コードは次のとおりです:function Person(name){ this.name =name;
}

person.prototype.share=[];

var person=new Person('Byron');
person.share=0;
console.log(person.share) // プロトタイプでは []



単純なオブジェクトの構築

もちろん、プロトタイプは上記の問題を解決するために特別に定義されているわけではありませんが、上記の問題を解決します。この知識を理解すると、インスタンス オブジェクトのプロパティや関数が必要な場合は、プロトタイプで定義し、各インスタンスに個別のプロパティやメソッドを持たせたい場合は、これをインスタンス化して定義します。パラメータはコンストラクタを介して渡すことができます。

コードをコピー

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。