ホームページ >ウェブフロントエンド >jsチュートリアル >JS プロトタイプ オブジェクトとプロトタイプ チェーン_JavaScript スキルに関する簡単な説明

JS プロトタイプ オブジェクトとプロトタイプ チェーン_JavaScript スキルに関する簡単な説明

WBOY
WBOYオリジナル
2016-05-16 15:12:241395ブラウズ

JavaScript ではすべてがオブジェクトですが、オブジェクトにも種類があり、通常のオブジェクト (Object) と関数オブジェクト (Function) の 2 つに大別されます。

一般に、new Function を通じて生成されたオブジェクトは Function オブジェクトであり、それ以外のオブジェクトは通常のオブジェクトです。

例:

function f1(){
  //todo
}
var f2 = function(){
  //todo
};
var f3 = new Function('x','console.log(x)');
 
var o1 = {};
var o2 = new Object();
var o3 = new f1();
 
console.log(
  typeof f1,//function
  typeof f2,//function
  typeof f3,//function
  typeof o1,//object
  typeof o2,//object
  typeof o3 //object
);
>> function function function object object object

f1 は関数宣言であり、関数を定義する最も一般的な方法です。f2 は実際には関数式である f2 に代入されますが、関数オブジェクトでもあります。 。

Function は JS に付属するオブジェクトです。f1 と f2 が作成されると、JS は new Function() を通じてこれらのオブジェクトを自動的に構築します。したがって、これら 3 つのオブジェクトはすべて new Function() によって作成されます。

JavaScript でオブジェクトを作成するには、オブジェクト リテラルと新しい式を使用する 2 つの方法があります。o1 と o2 の作成は、これら 2 つの方法に対応します。Java と C# を使用して理解する場合、o3 は次のとおりです。 f1、o3、f1 のインスタンス オブジェクトは同じ型です。少なくとも私はそう思っていましたが、そうではありません...

では、それをどのように理解すればよいでしょうか? それは非常に簡単です。o3 が関数オブジェクトではなく、通常のオブジェクトであるため、明らかにそうではありません。

関数オブジェクトと通常のオブジェクトを簡単に理解した後、JavaScript のプロトタイプとプロトタイプ チェーンを見てみましょう。

JS では、関数オブジェクト f1 が作成されるたびに、プロトタイプや __proto__ などのいくつかのプロパティがオブジェクトに組み込まれます。Prototype は、f1 のいくつかのプロパティとメソッドを記録するプロトタイプ オブジェクトです。

プロトタイプは f1 には見えないことに注意してください。つまり、f1 はプロトタイプ内のプロパティとメソッドを検索しません。

function f(){}
f.prototype.foo = "abc";
console.log(f.foo); //undefined

では、プロトタイプは何に役立つのでしょうか? 実際、プロトタイプの主な機能は継承です。 平たく言えば、プロトタイプで定義されたプロパティとメソッドは、それ自体の「子孫」用に予約されているため、サブクラスはプロトタイプのプロパティとメソッドに完全にアクセスできます。

f1 がどのようにプロトタイプを「子孫」に残すかを知るには、JS のプロトタイプチェーンを理解する必要があります。このとき、JS の __proto__ は非常に奇妙に見えますが、非常に隠されています。あまり目にしないことですが、この関数は通常のオブジェクトと関数オブジェクトの両方に存在し、JS が新しい式を通じてオブジェクトを作成するときに、通常は親クラスを保存します。クラスのプロトタイプは新しいオブジェクトの __proto__ 属性に割り当てられ、世代間の継承が形成されます...

function f(){}
f.prototype.foo = "abc";
var obj = new f();
console.log(obj.foo); //abc

obj の __proto__ が f のプロトタイプを保存することがわかりました。それでは、f のプロトタイプの __proto__ には何が保存されるのでしょうか。以下の図を見てください。

図に示すように、f.prototype の __proto__ に Object.prototype が格納されています。 出力結果から、Object.prototype.__proto__ は null となり、obj オブジェクトのプロトタイプを示します。 . チェーンの終わり。以下に示すように:

obj オブジェクトがそのようなプロトタイプチェーンを持った後、obj.foo が実行されると、obj は最初に属性を持っているかどうかを検索しますが、foo が見つからない場合、obj はプロトタイプに従います。チェーンして検索してください...

上記の例では、f のプロトタイプに foo 属性を定義しました。このとき、obj はプロトタイプ チェーン上でこの属性を見つけて実行します。

最後に、この記事に含まれる重要なポイントをいくつかの文でまとめます:

  • プロトタイプ チェーンの形成は実際にはプロトタイプではなく __proto__ に依存します。JS エンジンはオブジェクトのメソッドを実行するときに、まずオブジェクト自体にメソッドが存在するかどうかを検索します。存在しない場合は、プロトタイプ チェーンで検索されますが、独自のプロトタイプは見つかりません。
  • オブジェクトの __proto__ は、独自のプロトタイプ チェーンを記録し、独自のデータ型を決定します。__proto__ を変更することは、オブジェクトのデータ型を変更することと同じです。
  • 関数のプロトタイプは、独自のプロトタイプ チェーンに属しません。これはサブクラス作成の核心であり、サブクラスのデータ型を決定し、サブクラスのプロトタイプ チェーンを接続するブリッジです。 。
  • プロトタイプ オブジェクトのメソッドとプロパティを定義する目的は、サブクラスによって継承され、使用されることです。

以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。

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