1.プロトタイプオブジェクト
1.1コンストラクターの短所
JavaScriptはコンストラクターを介して新しいオブジェクトを生成するため、コンストラクターはオブジェクトのテンプレートと見なすことができます。インスタンスオブジェクトのプロパティとメソッドは、コンストラクター内で定義できます。
function cat(name、color){this.name = name; this.color = color;} var cat1 = new Cat( 'Big Hair'、 'White'); cat1.name // 'Big Hair'cat1.color //' White '上記のコードのCAT機能はコンストラクターです。名前属性と色属性は内部で定義されます。すべてのインスタンスオブジェクトは、これら2つの属性を生成します。ただし、同じコンストラクターのオブジェクトインスタンス間でプロパティを共有できないため、そうすることはシステムリソースの無駄です。
function cat(name、color){this.name = name; this.color = color; this.meow = function(){console.log( 'mew、mew、mew ...'); };} var cat1 = new cat( 'big hair'、 'white'); var cat2 = new cat( 'ei mao'、 'black'); cat1.meow === cat2.meow // false上記のコードでは、CAT1とCAT2は同じコンストラクターのインスタンスです。ただし、それらのMeowメソッドは異なります。つまり、新しいインスタンスが作成されるたびに、新しいMeowメソッドが作成されます。すべてのMEOWメソッドは同じ動作であり、完全に共有する必要があるため、これは必要でも廃棄物システムリソースでもありません。
1.2プロトタイプ属性の役割
JavaScript言語では、各オブジェクトには、プロトタイプオブジェクトと呼ばれる対応するプロトタイプオブジェクトがあります。プロトタイプオブジェクトで定義されているすべてのプロパティとメソッドは、派生オブジェクトによって継承できます。これは、JavaScript継承メカニズムの基本設計です。
このアプローチに加えて、JavaScriptはインスタンスオブジェクトを定義する別の方法も提供します。コンストラクターは関数、オブジェクトであり、独自のプロパティとメソッドもあることを知っています。 1つのプロトタイプ属性は、一般にプロトタイプオブジェクトと呼ばれる別のオブジェクトを指します。このオブジェクトは非常に特別です。その上に定義されているプロパティとメソッドがすべてのインスタンスオブジェクトで共有できる限り。つまり、コンストラクターがインスタンスオブジェクトを生成すると、プロトタイプ属性がインスタンスオブジェクトに自動的に割り当てられます。
function animal(name){this.name = name;} animal.prototype.color = "white"; var cat1 = new animal( 'big hair'); var cat2 = new Animal( 'erimao'); cat1.color // 'white'cat2.color //' white ''上記のコードは、コンストラクターアニマルのプロトタイプオブジェクトにカラー属性を追加します。その結果、両方のインスタンスがCAT1とCAT2をオブジェクトにしています。
より特に、プロトタイプオブジェクトが変更されている限り、変更はインスタンスオブジェクトにすぐに反映されます。
Animal.prototype.color = "Yellow"; cat1.color // 'Yellow'cat2.color //' Yellow '
上記のコードは、プロトタイプオブジェクトの色属性の値を黄色に変更し、2つのインスタンスオブジェクトの色属性の値がすぐに変更されます。これは、インスタンスオブジェクトに実際に色属性がなく、すべてプロトタイプオブジェクトの色属性を読み取るためです。つまり、インスタンスオブジェクト自体に特定のプロパティまたはメソッドがない場合、コンストラクターのプロトタイプオブジェクトに移動してプロパティまたはメソッドを見つけます。これは、プロトタイプオブジェクトに関する特別なことです。
インスタンスオブジェクト自体に特定のプロパティまたはメソッドがある場合、プロトタイプオブジェクトでこのプロパティまたはメソッドを探しません。
cat1.color = 'black'; cat2.color // 'yellow'animal.prototype.color // "Yellow";
上記のコードは、インスタンスオブジェクトCAT1の色プロパティを黒に変更するため、プロトタイプオブジェクトから色プロパティを読み取る必要がなくなり、後者の値はまだ黄色です。
要するに、プロトタイプオブジェクトの関数は、すべてのインスタンスオブジェクトで共有されるプロパティとメソッドを定義することであるため、インスタンスオブジェクトのプロトタイプとも呼ばれ、インスタンスオブジェクトはプロトタイプオブジェクトから派生したものと見なすことができます。
animal.prototype.walk = function(){console.log(this.name + 'is walking。');};上記のコードは、Animal.protypeオブジェクトのウォークメソッドを定義します。これは、すべての動物インスタンスオブジェクトで呼び出されます。
1.3プロトタイプチェーン
JavaScript内のすべてのオブジェクトにはコンストラクターがあり、すべてのコンストラクターにはプロトタイプ属性があるため(実際、すべての関数にはプロトタイプ属性があります)、すべてのオブジェクトには独自のプロトタイププロトタイプオブジェクトがあります。
したがって、オブジェクトのプロパティとメソッドは、それ自体またはそのプロトタイプオブジェクト(上記のコードのウォークメソッドなど)で定義できます。プロトタイプ自体はオブジェクトであり、独自のプロトタイプを持っているため、プロトタイプチェーンが形成されます。たとえば、オブジェクトAはオブジェクトBのプロトタイプ、オブジェクトBはオブジェクトCのプロトタイプなどです。ソースのルートをトレースするため、ソースのオブジェクトはオブジェクトコンストラクター(新しいオブジェクト()コマンドを使用)から生成されるため、レイヤーごとにレイヤーをトレースすると、すべてのオブジェクトのプロトタイプは最終的にObject.Prototypeにトレースできます。それで、object.prototypeのプロトタイプはありますか? Object.Prototypeのプロトタイプは、プロパティや方法のないヌルであるため、答えは「はい」または「いいえ」になる可能性があります。
object.getPrototypeof(object.prototype)// null
上記のコードは、object.prototypeオブジェクトのプロトタイプがnullであることを示しています。 Nullにはプロパティがないため、プロトタイプチェーンはここで終了します。
「プロトタイプチェーン」の機能は、オブジェクトの特定の属性を読み取るときに、JavaScriptエンジンが最初にオブジェクト自体の属性を探すことです。見つからない場合、そのプロトタイプを探します。まだ見つからない場合、プロトタイプのプロトタイプを探します。など、上部レベルのObject.Prototypeがまだ見つからない場合、未定義に戻ります。
たとえば、関数のプロトタイプ属性が配列を指している場合、生成するインスタンスオブジェクトはプロトタイプ属性を介して配列メソッドを呼び出すことができるため、関数を配列コンストラクターとして使用できることを意味します。
function myarray(){} myarray.prototype = new array(); myarray.prototype.constructor = myArray; var myarray(); mine.push(1、2、3); mine.lengt上記のコードの鉱山は、MyArrayのインスタンスオブジェクトです。 MyArrayのプロトタイププロパティはアレイを指しているため、鉱山は配列メソッドを呼び出すことができます(これらの方法は実際には配列のプロトタイプオブジェクトで定義されています)。式の最後のインスタンスについては、オブジェクトがコンストラクターのインスタンスであるかどうかを比較するためにインスタンスのインスタンスを使用していることがわかります。最後の行は、私のものが配列のインスタンスであることを示します。
アレイ//の鉱山インスタンスは(array === myarray.prototype.constructor)||(array === array.prototype.constructor)に相当します。
上記のコードは、インスタンスオブジェクトのすべてのプロトタイプオブジェクトのコンストラクター属性と比較される、オペレーターのインスタンスの本質を示しています(この属性の導入については、次のセクションを参照してください)。ある限り、それはtrueを返します。そうしないと、falseを返します。
1.4コンストラクター属性
プロトタイプオブジェクトには、プロトタイプオブジェクトがデフォルトで配置されているコンストラクター関数を指すコンストラクター属性があります。
関数p(){} p.prototype.constructor === p // trueコンストラクター属性はプロトタイプオブジェクトで定義されるため、すべてのインスタンスオブジェクトによって継承できることを意味します。
関数P(){} var p = new P(); p.constructor // function p(){} p.constructor === p.prototype.constructor // truep.hasownproperty( 'constructor')// false上記のコードは、PがコンストラクターPのインスタンスオブジェクトであることを示していますが、P自体にはコンストラクター属性がありません。これは実際にプロトタイプチェーンのP.Prototype.Constructor属性を読み取ります。
コンストラクター属性の関数は、プロトタイプオブジェクトが定義されているコンストラクターを区別することです。
関数f(){}; var f = new f(); f.constructor === f // truef.constructor === regexp // false上記のコードは、コンストラクタープロパティを使用して、変数fのコンストラクター関数がfではなくfであることを決定することを意味します。
2.Object.getProtopeofメソッド
object.getPrototypeofメソッドは、オブジェクトのプロトタイプを返します。
//空のオブジェクトのプロトタイプはobject.protopeobject.getPrototypeof({})=== object.prototype // true //関数のプロトタイプはfunction.proteffunction f(){} object.getPrototypeof(f)=== function.prototype Fはf.prototypevar f = new f(); object.getPrototypeof(f)=== f.prototype // true3.Object.Createメソッド
Object.Createメソッドは、新しいオブジェクトを生成するために使用され、新しいコマンドを置き換えることができます。オブジェクトを引数として受け入れ、前者のプロパティを完全に継承する新しいオブジェクトを返します。つまり、前者は後者のプロトタイプになります。
var o1 = {p:1}; var o2 = object.create(o1); o2.p // 1上記のコードでは、Object.CreateメソッドはO1に基づいてO2を生成します。この時点で、O1はO2のプロトタイプになります。つまり、O2はO1のすべての特性を継承します。
Object.Createメソッドは、基本的に次のコードと同等です。古いブラウザがobject.createメソッドをサポートしていない場合、次のコードを使用して自分で展開できます。
if(typeof object.create!== "function"){object.create = function(o){function f(){} f.prototype = o;新しいf()を返します。 };}上記のコードは、Object.Createメソッドが本質的に新しいコンストラクターFを作成し、Fのプロトタイプ属性がObject OをプロトタイプとしてPointoにすることを許可し、最後にFのインスタンスを返すようにして、インスタンスがOの属性を継承できるようにします。
次の3つの方法で生成された新しいオブジェクトは同等です。
var o1 = object.create({}); var o2 = object.create(object.prototype); var o3 = new object();プロパティ(ToStringやValue of Methodなど)を継承しないオブジェクトを生成する場合は、object.createパラメーターをnullに設定できます。
var o = object.create(null); o.valueof()// typeRror:オブジェクト[オブジェクトオブジェクト]はメソッド「値」がありません
上記のコードは、オブジェクトOのプロトタイプがnullの場合、object.prototypeオブジェクトにいくつかのプロパティが定義されていないことを示しています。
object.createメソッドを使用する場合、オブジェクトのプロトタイプを提供する必要があります。そうしないと、エラーが報告されます。
object.create()// typeRror:オブジェクトプロトタイプはオブジェクトまたはnullのみである可能性があります
Object.createメソッドによって生成された新しいオブジェクトは、プロトタイプを動的に継承します。プロトタイプにメソッドを追加または変更すると、新しいオブジェクトにすぐに反映されます。
var o1 = {p:1}; var o2 = object.create(o1); o1.p = 2; o2.p // 2上記のコードは、オブジェクトのプロトタイプを変更すると、新しく生成されたオブジェクトに影響することを示しています。
オブジェクトプロトタイプに加えて、Object.createメソッドは、object.definePropertiesメソッドと同じ形式である属性を記述する属性オブジェクトを表す2番目のパラメーターも受け入れることができます。記述するオブジェクトプロパティは、新しいオブジェクトに追加されます。
var o = object.create(object.prototype、{p1:{value:123、列挙可能:true}、p2:{value: "abc"、列挙可能:true}}); o.p1 // 123o.p2 // "abc" "Object.Createメソッドはコンストラクターを使用していないため、オブジェクトがどのコンストラクターインスタンスであるかを決定するために使用することはできません。この時点で、次のISProtopeofメソッドを使用して、プロトタイプがどのオブジェクトであるかを解釈できます。
4.ISPROTOTYPEOFメソッド
ISPrototypeofメソッドは、オブジェクトが別のオブジェクトのプロトタイプであるかどうかを判断するために使用されます。
var o1 = {}; var o2 = object.create(o1); var o3 = object.create(o2); o2.isprototypeof(o3)// trueo1.isprototypeof(o3)// true上記のコードは、オブジェクトがプロトタイプチェーン上にある限り、isprotypeofが真実であることを示しています。
5。簡単な例
var classdemo = function(){// static private変数var private_static_var = 'aaaa'; // static private method var private_static_func = function(key){return key + private_static_var; } //プライベートメソッド、キーはこのvar private_func = function(self、key){private_static_func(key + self.id); } var _class = function(id){// constructor this.id = id; // public変数} // public Method_class.prototype.public_func = function(key){return private_func(this、key); } return _class;}(); var a = new classdemo( 'hello world'); alert(a.public_func( 'world hello'));プライベート変数とパブリックの静的変数/メソッドを実装する簡単な方法はありませんが、この程度までカプセル化するには十分です。