ホームページ > 記事 > ウェブフロントエンド > JavaScript のプロトタイプとは正確には何ですか_javascript のヒント
JavaScript もオブジェクト指向言語ですが、クラスベースの言語ではなく、プロトタイプベースの言語です。 JavaScript では、クラスとオブジェクトの間に大きな違いはないようです。
プロトタイプとは:
関数で定義されたオブジェクトにはプロトタイプ属性があり、プロトタイプ属性はプロトタイプ・オブジェクトを指します。プロトタイプ属性とプロトタイプ・オブジェクトは別のものであるため、その違いに注意してください。プロトタイプ オブジェクトには別のコンストラクター属性があり、このコンストラクター属性もコンストラクター オブジェクトを指しており、このコンストラクター オブジェクトはまさに関数そのものです。 とても複雑ではありませんか?擬似コードで表現すると次のようになります:
var function{ prototype:prototype{ constructor:constructor == function } }
まだ理解できませんか?写真を見てください:
プロトタイプの役割:
このプロトタイプは具体的に何をするのでしょうか?以下の例を見てください:
function jb51(){ } jb51.prototype.name = "a"; var test = new jb51(); alert(test.name)//"a";
奇妙なことに、明らかに name 属性がテスト用に設定されていないのに、なぜ値があるのでしょうか?
これはプロトタイプの貢献です。uw3c のプロトタイプ属性内の name オブジェクトは、新しいコンストラクターによって uw3c が作成された後、オブジェクト test の属性に継承されます。次に読む:
var name = "js"; function jb51(name){ alert(this.name);//"css" } jb51.prototype.name = "css"; var test = new jb51(); test()
alert の値が「js」ではないのはなぜですか?プロセスは大まかに次のとおりです。
var test={}; uw3c.call(test);
最初のステップは、新しいオブジェクト (テスト) を作成することです。
2 番目のステップは、オブジェクト (テスト) の組み込みプロトタイプ オブジェクトを、コンストラクター (つまり、uw3c) のプロトタイプ属性によって参照されるプロトタイプ オブジェクトに設定することです。
3 番目のステップは、オブジェクト (test) をパラメータとして使用してコンストラクター (つまり、uw3c) を呼び出し、メンバー設定などの初期化作業を完了することです。
2 番目のステップで登場した新しい用語は、組み込みプロトタイプ オブジェクトです。この新しい用語は、プロトタイプ オブジェクトと同じものではないことに注意してください。これを inobj と呼びます。inobj は、関数 uw3c のプロトタイプ オブジェクト。 uw3c のプロトタイプ オブジェクトに表示されるプロパティや関数は、テスト オブジェクトで直接使用できます。これが JS のプロトタイプの継承です。
通常、次のようなオブジェクトを作成します:
function person(name){ this.sayHi = function(){ alert('hi ' + this.name); } this.name = name; } var p = new person("dan"); p.sayHi();
上では、 new キーワードを使用して、オブジェクトを通じてオブジェクト インスタンスを作成します (関数も特別なオブジェクトです)。
クラスベースの言語では、通常、属性またはフィールドはクラス内で事前に定義されますが、JavaScript では、オブジェクトの作成後にフィールドをクラスに追加できます。
function animal(){} var cat = new animal(); cat.color = "green";
上記では、color フィールドは現在の cat インスタンスにのみ属します。
後で追加したフィールドについて、animal のすべてのインスタンスにフィールドを持たせたい場合はどうすればよいでしょうか?
--使用Prototype function animal(){} animal.prototype.color= "green"; var cat = new animal(); var dog = new animal(); console.log(cat.color);//green console.log(dog.color);//green
プロトタイプを通じてフィールドを追加できるだけでなく、メソッドも追加できます。
function animal(){} animal.prototype.color= "green"; var cat = new animal(); var dog = new animal(); console.log(cat.color);//green console.log(dog.color);//green animal.prototype.run = funciton(){ console.log("run"); } dog.run();
prototype 属性を使用すると、オブジェクトの作成後にその動作を変更することもできることがわかりました。
たとえば、配列と呼ばれる特別なオブジェクトにメソッドを追加できます。
Array.prototype.remove = function(elem){ var index = this.indexof(elem); if(index >= 0){ this.splice(index, 1); } } var arr = [1, 2, 3] ; arr.remove(2);
プロトタイプを通じてオブジェクトのプロパティやメソッドを定義するだけでなく、オブジェクトのコンストラクターを通じてクラスのプロパティやメソッドを定義することもできます。
function animal(){ this.color = "green"; this.run = function(){ console.log("run"); } } var mouse = new animal(); mouse.run();
上記のアプローチにより、すべての動物インスタンスがすべてのフィールドとメソッドを共有できるようになります。もう 1 つの利点は、コンストラクターでクラスのローカル変数を使用できることです。
function animal(){ var runAlready = false; this.color = "green"; this.run = funciton(){ if(!runAlreadh){ console.log("start running"); } else { console.log("already running") } } }
実際、より実用的なアプローチは、プロトタイプと組み合わせたコンストラクターを通じてクラスのフィールドと動作を定義することです。
function animal(){ var runAlready = false; this.run = function(){ if(!runAlready){ console.log('i am running'); } else { console.log("i am already running"); } } } animal.prototype.color = ''; animal.prototype.hide = funciton(){ console.log(""); } var horse = new animal(); horse.run(); horse.hide();
プロトタイプを使用すると、オブジェクトの作成後にオブジェクトまたはクラスの動作を変更できます。プロトタイプ属性を通じて追加されたこれらのフィールドまたはメソッドは、すべてのオブジェクト インスタンスで共有されます。