Javaなどの典型的なオブジェクト指向言語では、クラスの概念があります。クラスはオブジェクトのテンプレートであり、オブジェクトはクラスのインスタンスです。ただし、JavaScript言語システムでは、クラスの概念はありません。 JavaScriptは「クラス」に基づいているのではなく、コンストラクターとプロトタイプチェーンを介して実装されています。ただし、ES6は、従来の言語に近いライティング方法を提供し、クラス(クラス)の概念をオブジェクトテンプレートとして紹介します。クラスキーワードを使用して、クラスを定義できます。基本的に、ES6のクラスは単なる構文糖と見なすことができます。その機能のほとんどは、ES5によって達成できます。新しいクラスライティング方法は、プロトタイプオブジェクトのみを、オブジェクト指向のプログラミング構文のように、より明確で、より類を見ないものにします。
私の習慣によれば、私はそれを書く前に記事ディレクトリを提供します。
次のコンテンツは、次のサブセクションに分割されます。
1.コンストラクターの簡単な紹介
2。コンストラクターの短所
3。プロトタイプ属性の役割
4。プロトタイプチェーン
5.構成属性属性
5.1:コンストラクター属性の役割
6.オペレーターのインスタンス
1.コンストラクターの簡単な紹介
コンストラクターとJavaScriptの新しいコマンドとの密接な関係に関する私の記事では、コンストラクターの概念と特性、新しいコマンドなどの原則と使用法が詳細に紹介されています。コンストラクターに慣れていない場合は、注意深く行って味わうことができます。簡単なレビューです。
いわゆるコンストラクターは、オブジェクトを生成するためのテンプレートを提供し、オブジェクトの基本構造を記述する関数です。コンストラクターは、それぞれ同じ構造を持つ複数のオブジェクトを生成できます。一般に、コンストラクターはオブジェクトのテンプレートであり、オブジェクトはコンストラクターのインスタンスです。
コンストラクターの特性は次のとおりです。
A:コンストラクターの関数名の最初の文字を大文字にする必要があります。
B:このオブジェクトを内部的に使用して、生成されるオブジェクトインスタンスを指します。
C:新しい演算子を使用してコンストラクターを呼び出し、オブジェクトインスタンスを返します。
最も簡単な例を見てみましょう。
function person(){this.name = 'keith';} var boy = new person(); console.log(boy.name); //「キース」2。コンストラクターの短所
すべてのインスタンスオブジェクトは、コンストラクター内のプロパティとメソッドを継承できます。ただし、同じオブジェクトインスタンス間でプロパティを共有することはできません。
function person(name、height){this.name = name; this.height = height; this.hobby = function(){return 'watching movies';}} var boy = new person( 'keith'、180); var girl = new Person( 'Rascal'、153); console.log(boy.name); // 'keith' console.log(girl.name); // 'rascal' console.log(boy.hobby === girl.hobby); //間違い上記のコードでは、コンストラクターの人が2つのオブジェクトインスタンスボーイと女の子を生成し、2つのプロパティとメソッドを持っています。ただし、趣味の方法は異なります。つまり、コンストラクターを呼び出してオブジェクトインスタンスを元に戻すために新しい使用を使用するたびに、趣味の方法が作成されます。すべての趣味の方法は幼稚な行動であり、2つのオブジェクトインスタンスで完全に共有できるため、これはリソースの無駄でもありません。
したがって、コンストラクターの欠点は、同じコンストラクターのオブジェクトインスタンス間でプロパティまたはメソッドを共有できないことです。
3。プロトタイプ属性の役割
コンストラクターのオブジェクトインスタンス間でプロパティを共有できないという欠点を解決するために、JSはプロトタイプ属性を提供します。
JSの各データ型はオブジェクト(null and未定義を除く)であり、各オブジェクトは別のオブジェクトから継承され、後者は独自のプロトタイプオブジェクトを持たないnullを除き、「プロトタイプ」オブジェクトと呼ばれます。
プロトタイプオブジェクトのすべてのプロパティとメソッドは、オブジェクトインスタンスによって共有されます。
オブジェクトインスタンスがコンストラクターを介して生成されると、オブジェクトインスタンスのプロトタイプは、コンストラクターのプロトタイププロパティを指します。各コンストラクターには、オブジェクトインスタンスのプロトタイプオブジェクトであるプロトタイプ属性があります。
function person(name、height){this.name = name; this.height = height; } person.prototype.hobby = function(){return 'watching movies'; } var boy = new person( 'keith'、180); var girl = new Person( 'Rascal'、153); console.log(boy.name); // 'keith' console.log(girl.name); // 'rascal' console.log(boy.hobby === girl.hobby); //真実上記のコードでは、趣味の方法がプロトタイプオブジェクトに配置されている場合、両方のインスタンスオブジェクトが同じ方法を共有します。コンストラクターにとって、プロトタイプはコンストラクターとしてのプロパティであることを誰もが理解できることを願っています。オブジェクトインスタンスの場合、プロトタイプはオブジェクトインスタンスのプロトタイプオブジェクトです。したがって、プロトタイプはプロパティとオブジェクトです。
プロトタイプオブジェクトは、オブジェクトインスタンスのプロパティではありません。オブジェクトインスタンスの属性は、コンストラクター内に生成されるオブジェクトインスタンスを指すキーワードがあるため、コンストラクターの定義から継承される属性です。オブジェクトインスタンスのプロパティは、実際にはコンストラクターによって内部的に定義されている属性です。プロトタイプオブジェクトのプロパティとメソッドが変更されている限り、変更はすべてのオブジェクトインスタンスに直ちに反映されます。
person.prototype.hobby = function(){return 'shimmis'; } console.log(boy.hobby === girl.hobby); // true Console.log(boy.hobby()); // 'shimply'console.log(girl.hobby()); //'水泳'上記のコードでは、プロトタイプオブジェクトの趣味の方法を変更した後、両方のオブジェクトインスタンスが変更されました。これは、オブジェクトインスタンスには実際には趣味の方法がないため、プロトタイプオブジェクトを読む趣味の方法です。つまり、オブジェクトインスタンスにプロパティとメソッドがない場合、プロトタイプオブジェクトで検索します。インスタンスオブジェクト自体に特定のプロパティまたはメソッドがある場合、プロトタイプオブジェクトでは検索されません。
boy.hobby = function(){return 'play basketball'; } console.log(boy.hobby()); // 'Play Basketball' Console.log(girl.hobby()); //'水泳'上記のコードでは、Boy Objectインスタンスの趣味の方法が変更されている場合、プロトタイプオブジェクトの趣味の方法は継承されません。ただし、少女はプロトタイプオブジェクトの方法を引き続き継承します。
要約するには:
A:プロトタイプオブジェクトの機能は、すべてのオブジェクトインスタンスで共有されるプロパティとメソッドを定義することです。
B:プロトタイプ、コンストラクター向け、それはプロパティです。オブジェクトインスタンスの場合、それはプロトタイプオブジェクトです。
4。プロトタイプチェーン
オブジェクトのプロパティとメソッドは、それ自体またはそのプロトタイプオブジェクトで定義できます。プロトタイプオブジェクト自体はオブジェクトインスタンスであり、独自のプロトタイプも備えているため、プロトタイプチェーンが形成されます。たとえば、オブジェクトAはオブジェクトBのプロトタイプ、オブジェクトBはオブジェクトCのプロトタイプなどです。すべてのオブジェクトのプロトタイプの最上部は、Object.prototype、つまり、オブジェクトコンストラクターのプロトタイププロパティによって指摘されているオブジェクトです。
もちろん、Object.Prototypeオブジェクトには、独自のプロトタイプオブジェクト、つまり属性とメソッドのないヌルオブジェクトもあり、nullオブジェクトには独自のプロトタイプがありません。
1 console.log(object.getPrototypeof(object.prototype)); // null
2 Console.log(person.prototype.isprototypeof(boy))// true
プロトタイプチェーンの特性は次のとおりです。
A:オブジェクトの特定のプロパティを読み取るとき、JavaScriptエンジンは最初にオブジェクト自体のプロパティを探します。見つからない場合は、プロトタイプに移動します。それでも見つからない場合は、プロトタイプのプロトタイプに移動します。上部レベルのObject.Prototypeがまだ見つからない場合、未定義が返されます。
B:オブジェクト自体とそのプロトタイプが同じ名前の属性を定義する場合、オブジェクト自体の属性が最初に読み取られます。これは「オーバーライド」と呼ばれます。
C:プロトタイプチェーンレベルで特定の属性を探していることは、パフォーマンスに影響を与えます。探しているプロトタイプオブジェクトのレベルが高いほど、パフォーマンスへの影響が大きくなります。存在しないプロパティを探すと、プロトタイプチェーン全体を横断します。
概念を見るのはあいまいなことかもしれません。例を見てみましょう。しかし、概念を理解することは本当に重要です。
var arr = [1,2,3]; console.log(arr.length); //3CONSOLE.LOG(arr.Valueof())// [1,2,3] Console.log(arr.join( '|'))// 1 | 2 | 3
上記のコードでは、アレイARRが定義され、3つの要素が配列にあります。アレイに属性やメソッドを追加しませんでしたが、長さ、join()、およびvalueof()を呼び出すときにエラーを報告しませんでした。
長さの属性はarray.prototypeから継承され、プロトタイプオブジェクト上のプロパティに属します。結合方法は、array.prototypeからも継承され、プロトタイプオブジェクトのメソッドに属します。これらの2つの方法は、すべての配列で共有されます。インスタンスオブジェクトに長さの属性がない場合、プロトタイプオブジェクトが検索されます。
valueofメソッドは、object.prototypeから継承されます。まず第一に、arr配列には価値がないため、プロトタイプオブジェクト配列を調べてください。プロトタイプ。次に、array.prototypeオブジェクトにvalueofメソッドがないことがわかりました。最後に、object.prototypeオブジェクトを検索します。
それぞれArray.PrototypeオブジェクトとObject.Prototypeオブジェクトのプロパティと方法を見てみましょう。
console.log(object.getownPropertynames(array.prototype))// 「マップ」、「フィルター」、「Reduceright」、「some "、" every "、" find "、" indindex "、" copywithin "、" fill "、" antries "、" keys "、" keys "、" values "、" include "、" $ set "、" $ remove "] console.log(object。 「toString」、「tolocalestring」、「value of」、「watch」、「watch」、 "hasownProperty"、 "isprototypeof"、 "propertyisenumerable"、 "__definegetter__"、 "__defineetter__"、 "__lookupgetter__"、 "__pruction
あなたがこれを見るとき、あなたはまだプロトタイプについて非常にわずかな理解を持っていると信じています。これは正常です。結局のところ、それはJSのより重要で抽象的な概念です。迅速にマスターすることは不可能です。さらにいくつかの記事を食べた場合、本質を習得することができます。特定の方法では、生きている例がありますが、これは誰もが遭遇する問題である可能性があります。 JSコンストラクターとプロトタイプオブジェクトをご覧ください。
5.構成属性属性
プロトタイプオブジェクトには、プロトタイプオブジェクトがデフォルトで配置されているコンストラクター関数を指すコンストラクター属性があります。
関数a(){}; console.log(a.prototype.constructor === a)// trueプロトタイプはコンストラクターのプロパティであり、コンストラクターはコンストラクターのプロトタイププロパティ、つまりプロトタイプオブジェクトのプロパティによって指摘されているオブジェクトであることに注意する必要があります。混乱しないように注意してください。
console.log(a.hasownproperty( 'prototype')); // true Console.log(a.prototype.hasownproperty( 'constructor')); //真実
コンストラクター属性はプロトタイプオブジェクトで定義されるため、すべてのインスタンスオブジェクトによって継承できることを意味します。
関数a(){}; var a = new a(); console.log(a.constructor); //a()Console.log(a.constructor===a.prototype.constructor);//true上記のコードでは、AはコンストラクターAのインスタンスオブジェクトですが、A自体には実際にプロトタイプチェーンを読み取っているコンストラクター属性がありません。
A.Prototype.Constructorプロパティ。
5.1:コンストラクター属性の役割
A:どのコンストラクター関数が属するプロトタイプオブジェクトであるかを決定します
関数a(){}; var a = new a(); console.log(a.constructor === a)// true console.log(a.constructor === array)// false上記のコードは、コンストラクタープロパティを使用して、インスタンスオブジェクトAのコンストラクター関数が配列ではなくaであることを決定することを意味します。
B:インスタンスから別のインスタンスを作成します
関数a(){}; var a = new a(); var b = new a.constructor(); console.log(b instanceof a); //真実上記のコードでは、AはコンストラクターAのインスタンスオブジェクトであり、コンストラクターはA.Constructorから間接的に呼び出されます。
C:独自のコンストラクターを呼び出すことができます
a.prototype.hello = function(){return new this.constructor(); }D:コンストラクターから別のコンストラクターを継承するパターンを提供します
function father(){} function son(){son.height.constructor.call(this); } son.height = new父();上記のコードでは、父と息子は両方ともコンストラクターです。息子の中に父親を呼ぶことは、息子が父親を継承する効果を形成します。
E:コンストラクター属性はプロトタイプオブジェクトとコンストラクターとの関係であるため、プロトタイプオブジェクトを変更するときは、コンストラクターのポインティング問題に注意を払う必要があります。
2つのソリューションがあります。コンストラクター属性を元のコンストラクター関数に指すか、プロトタイプオブジェクトにプロパティとメソッドを追加して、歪みのインスタンスを回避するだけです。
6.オペレーターのインスタンス
インスタンスのオペレーターは、指定されたオブジェクトがコンストラクターのインスタンスであるかどうかを示すブール値を返します。
関数a(){}; var a = new a(); console.log(a instance of a); //真実InstanceOFはプロトタイプチェーン全体のオブジェクトに対して有効であるため、同じインスタンスオブジェクトが複数のコンストラクターに対してTRUEを返す場合があります。
関数a(){}; var a = new a(); console.log(a instance of a); //trueconsole.log(a instanceof object); //真実オブジェクトのインスタンスは、複雑なデータ型(配列、オブジェクトなど)にのみ使用でき、単純なデータ型(ブール値、数字、文字列など)には使用できないことに注意してください。
var x = [1]; var o = {}; var b = true; var c = 'string'; console.log(x instanceof array); //trueconsole.log(o obsion offer object); // true Console.log(b booleanのinstance); //falseconsole.log(c instanceof string); //間違いまた、nullも未定義でもないものはオブジェクトではないため、インスタンスは常にfalseを返します。
console.log(null instanceof object); // false Console.log(オブジェクトの未定義のインスタンス); //間違い
インスタンスのオペレーターを使用して、コンストラクターを呼び出すときに新しいコマンドを追加することを忘れるという問題を巧みに解決することもできます。
function keith(name、height){if(!this Instanceof keith){return new Keith(name、height); } this.name = name; this.height = height;}上記のコードでは、OftenceOF演算子を使用して、関数本文のキーワードがコンストラクターKeithのインスタンスを指しているかどうかを判断します。そうでない場合、それは新しいコマンドが忘れられていることを意味します。この時点で、コンストラクターはオブジェクトインスタンスを返して、予期しない結果を回避します。
スペースの制限のため、私はここでそれをここに紹介します。
次の共有では、object.getPrototypeof()、object.setPrototypeof()などのプロトタイプオブジェクトのネイティブ方法について説明し、ネイティブオブジェクトを取得する方法の比較を紹介します。
上記は、編集者が紹介したJavaScriptのプロトタイプ属性(推奨)の詳細な説明です。それがあなたに役立つことを願っています。